如何在观察CancellationToken的同时等待一个等待对象?

时间:2015-10-19 08:16:00

标签: c# asynchronous async-await task-parallel-library system.reactive

我有一个等待的对象,它不是 local: { strategy: require('passport-local').Strategy, options: { usernameField: 'username' } } (例如,安装了RX的Task)。我想创建一个IObservable<T>,如果提供的Task被取消,最终将被取消,否则返回等待对象的结果。我想出了以下代码:

CancellationToken

使用这种方法,我将需要为我将使用的每个等待类型重载/重写最后两种方法。有没有更好的方法来做到这一点?我的猜测是public static Task ObserveTokenAsync(CancellationToken token) { TaskCompletionSource<Unit> tcs = new TaskCompletionSource<Unit>(); token.Register(() => tcs.SetCanceled()); return tcs.Task; } public static async Task<T> WrapObservableAsync<T>(IObservable<T> obs) { return await obs; } public static async Task<T> AwaitWhileObservingTokenAsync<T>(IObservable<T> obs, CancellationToken token) { var obsTask = WrapObservableAsync(obs); var tokenTask = ObserveTokenAsync(token); await Task.WhenAny(obsTask, tokenTask).ConfigureAwait(false); token.ThrowIfCancellationRequested(); return obsTask.Result; } 接口可能在某种程度上有用。

此外,如果提供的令牌不会被取消,INotifyCompletion方法是否会导致某种资源/内存泄漏?如果是,将ObserveTokenAsync设置为在TaskCompletionSource方法结束时完成将是解决问题的好方法吗?

1 个答案:

答案 0 :(得分:6)

使用Rx中的TaskObservableExtensions.ToTask扩展名方法。它需要一个CancellationToken,并且在可用时将从observable中取出最后一个元素来完成返回的任务。取消CancellationToken后,返回的任务将在等待时抛出OperationCanceledException。如果observable不包含任何元素,则返回的任务将在等待时抛出异常(可能是InvalidOperationException,但我必须查看它。)