ras*_*asx 7 c# task-parallel-library system.reactive
为什么要task永远等待?:
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();
Run Code Online (Sandbox Code Playgroud)
我知道"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();
}
Run Code Online (Sandbox Code Playgroud)
在哪里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;
}
Run Code Online (Sandbox Code Playgroud)
更新:这有点可怕(但它确实有效):
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;
}
Run Code Online (Sandbox Code Playgroud)
Bra*_*don 13
无论RunAsync和ToTask产生的最后的值中观察到.因此,在观察完成之前不会产生任何价值.但是创建的可观察量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();
Run Code Online (Sandbox Code Playgroud)