c# – IObservable.ToTask方法返回等待激活的Task
发布时间:2020-12-15 18:26:39 所属栏目:百科 来源:网络整理
导读:为什么任务永远等待?: var task = Observable .FromEventPatternMessageResponseEventArgs(communicator,"PushMessageRecieved") .Where(i = i.EventArgs.GetRequestFromReceivedMessage().Name == requestName) .Select(i = i.EventArgs) .RunAsync(Syste
为什么任务永远等待?:
var task = Observable .FromEventPattern<MessageResponseEventArgs>(communicator,"PushMessageRecieved") .Where(i => i.EventArgs.GetRequestFromReceivedMessage().Name == requestName) .Select(i => i.EventArgs) .RunAsync(System.Threading.CancellationToken.None) .ToTask(); task.Wait(); 我知道“PushMessageRecieved”被解雇了;我可以在Select lambda上设置一个断点并点击它.但task.Wait()永远不会移动. 更好的更新:FirstAsync()是我正在寻找的: public static Task<MessageResponseEventArgs> HandlePushMessageRecievedAsync(this ICommunicator communicator,RequestName requestName) { if (communicator == null) return Task.FromResult<MessageResponseEventArgs>(null); var observable = GetCommunicatorObservableForPushMessageReceived(communicator); return observable .Where(i => i.GetRequestFromReceivedMessage().Name == requestName) .Select(i => i) .FirstAsync() .ToTask(); } 其中GetCommunicatorObservableForPushMessageReceived()是: static IObservable<MessageResponseEventArgs> GetCommunicatorObservableForPushMessageReceived(ICommunicator communicator) { if (communicatorObservableForPushMessageReceived == null) { communicatorObservableForPushMessageReceived = Observable .FromEventPattern<MessageResponseEventArgs>(communicator,"PushMessageRecieved") .Where(i => !IsPreviousMessage(i.EventArgs.GetRequestFromReceivedMessage().EventId)) .Select(i => i.EventArgs); } return communicatorObservableForPushMessageReceived; } 更新:这有点可怕(但它确实有效): public static Task<MessageResponseEventArgs> HandlePushMessageRecievedAsync(this ICommunicator communicator,RequestName requestName) { if (communicator == null) return Task.FromResult<MessageResponseEventArgs>(null); var completionSource = new TaskCompletionSource<MessageResponseEventArgs>(); Observable .FromEventPattern<MessageResponseEventArgs>(communicator,"PushMessageRecieved") .Where(i => i.EventArgs.GetRequestFromReceivedMessage().Name == requestName) .Select(i => i.EventArgs) .ToEvent().OnNext += (args) => { if (args.Response.Errors != null && args.Response.Errors.Any()) { completionSource.TrySetException(args.Response.Errors.Select(j => new Exception(j.ErrorMessage))); } else { completionSource.TrySetResult(args); } }; return completionSource.Task; } 解决方法
RunAsync和ToTask都生成observable中的最后一个值.因此,在观察完成之前不会产生任何价值.但是使用FromEventPattern创建的可观察量通常不会完成.你需要强迫他们完成Take或Until之类的东西.
我还要注意RunAsync和ToTask本质上是多余的,不需要两者兼顾. 在你的情况下,我假设你真的对通过你的过滤器的第一个值感兴趣: var task = Observable .FromEventPattern<MessageResponseEventArgs>(communicator,"PushMessageRecieved") .FirstAsync(i => i.EventArgs.GetRequestFromReceivedMessage().Name == requestName) .Select(i => i.EventArgs) .ToTask(); task.Wait(); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |