我有一个不等于Task
的等待对象(例如,安装了RX的IObservable<T>
)。我想创建一个Task
,如果提供的CancellationToken
被取消,它将最终取消,否则返回等待对象的结果。我想出了下面的代码:如何在观察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;
}
采用这种方法,我将需要重载/重写了最后两个方法为每个awaitable类型,我将使用的。有没有更好的方法来做到这一点?我的猜测是,INotifyCompletion
接口可能在某种程度上是有用的。
此外,如果提供的标记不会被取消,那么ObserveTokenAsync
方法是否会导致某种资源/内存泄漏?如果是的话,将AwaitWhileObservingTokenAsync
方法末尾的TaskCompletionSource
设置完成将是解决问题的好方法吗?
你为什么要改变Rx?它通常要强大得多。 – Enigmativity
@Enigmativity我正在处理的问题是由非常复杂的状态描述的。我发现逻辑很难用功能的方式来表达。因此,我主要使用RX进行一些线程间通信,而大部分软件都是以命令式方式编写的。 – tearvisus
所以这是一个XY问题。也许这可能值得你一段时间来描述你实际上想要做的事情。在某些情况下,Rx非常擅长降低代码的复杂性。也许这里可能有一个很好的解决方案。 – Enigmativity