我有一个等待的对象,它不是 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
方法结束时完成将是解决问题的好方法吗?
答案 0 :(得分:6)
使用Rx中的TaskObservableExtensions.ToTask
扩展名方法。它需要一个CancellationToken
,并且在可用时将从observable中取出最后一个元素来完成返回的任务。取消CancellationToken
后,返回的任务将在等待时抛出OperationCanceledException
。如果observable不包含任何元素,则返回的任务将在等待时抛出异常(可能是InvalidOperationException
,但我必须查看它。)