ast*_*ker 17 c# asynchronous async-await cancellationtokensource taskcompletionsource
我有这样的代码(在这里简化)等待完成任务:
var task_completion_source = new TaskCompletionSource<bool>();
observable.Subscribe(b =>
{
if (b)
task_completion_source.SetResult(true);
});
await task_completion_source.Task;
Run Code Online (Sandbox Code Playgroud)
这个想法是订阅并等待true布尔流.这完成了"任务",我可以继续前进await.
但是我想取消 - 但不是订阅,而是等待.我想传递取消令牌(不知何故),task_completion_source所以当我取消令牌源时,await将继续前进.
怎么做?
更新:CancellationTokenSource这个代码是外部的,我这里所有的都是来自它的令牌.
Evk*_*Evk 20
如果我理解正确,你可以这样做:
using (ct.Register(() => {
// this callback will be executed when token is cancelled
task_comletion_source.TrySetCanceled();
})) {
// ...
await task_comletion_source.Task;
}
Run Code Online (Sandbox Code Playgroud)
请注意,它将在您的await上抛出异常,您必须处理该异常.
我建议你不要自己构建它.取消令牌周围有很多边缘案例,这些案例很难完成.例如,如果Register从未处理从中返回的注册,则最终可能会导致资源泄漏.
相反,您可以使用Task.WaitAsync我的AsyncEx.Tasks库中的扩展方法:
var task_completion_source = new TaskCompletionSource<bool>();
observable.Subscribe(b =>
{
if (b)
task_completion_source.SetResult(true);
});
await task_completion_source.Task.WaitAsync(cancellationToken);
Run Code Online (Sandbox Code Playgroud)
另外,我强烈建议您使用ToTask而不是明确TaskCompletionSource.再次,ToTask很好地处理边缘情况.