Asynchronous 异步{try…finally…}的finally没有被调用的可能原因是什么?涉及的处方
我有这样的想法:Asynchronous 异步{try…finally…}的finally没有被调用的可能原因是什么?涉及的处方,asynchronous,f#,system.reactive,cancellation,Asynchronous,F#,System.reactive,Cancellation,我有这样的想法: let a = async { try do! Async.AwaitTask someTask finally // clean up } Async.Start (a, cancellationTokenSource.Token) 当在a中等待的任务完成时,最后执行块并完成清理,但当asynca由于调用cancellationTokenSource而被取消时,不会执行清理。事实
let a =
async {
try
do! Async.AwaitTask someTask
finally
// clean up
}
Async.Start (a, cancellationTokenSource.Token)
当在a
中等待的任务完成时,最后执行块并完成清理,但当asynca
由于调用cancellationTokenSource
而被取消时,不会执行清理。事实上,我怀疑a
一直在运行
我真的没有线索,所以这里有一个初步的猜测:不,我真的没有猜测
编辑
问题似乎出在a
正在等待的任务中。
如果someTask
是:
Async.Ignore (Async.AwaitIAsyncResult <| Task.Delay(5000))
(vm
是一个视图模型。Finished
是一个事件。基本上,我希望a
由于取消或Finished
发生在vm
中而结束)
然后,a
拒绝被取消,或者最后被跳过,我不知道是哪个。在.Net中取消是合作的。这意味着,一旦任务开始,发出CancellationToken
的信号就没有实际效果,除非您对其进行监控
要启用取消,您需要在实际操作中选中CancellationToken.IsCancellationRequested
,如果为true,则结束它。或者您可以调用CancellationToken.ThrowIfCancellationRequested
以引发结束操作的异常。您需要将CancellationToken
传递给ToTask()
,否则无法取消
使用。您能发布完整的样本吗?请注意,任务需要测试其是否已取消。如果没有,就不会取消。你是对的。我通过将取消令牌传递给ToTask
解决了这个问题。我遇到了双重麻烦,因为我没有意识到Async.CancellationToken返回一个Async,当传递给ToTask时,它调用了错误的重载--晚了一秒!但是是的,这就是解决问题的方法。事实上,你的答案更明确,所以…我真正的问题是我调用了错误的重载。我没有意识到,我也必须让!ct=Async.CancellationToken
vm.Finished.Select(ignore).FirstAsync().ToTask()