我正在努力弄清楚如何在异步计算表达式中编写 Task.ContinueWith 。
最终,我想在不依赖取消例外的情况下处理取消。结果,我想我可以使用 Task.ContinueWith 。
但是,我试图写这篇文章时我已经不在了。
有什么建议吗?
let rec receiveXmlMessage connection (cancellation:CancellationToken) queue =
async {
use receiveCommand = new SqlCommand(receiveQuery, connection, CommandTimeout = 0)
let result = receiveCommand.ExecuteNonQueryAsync(cancellation)
result.ContinueWith(fun (someResult:Task<int>) -> CancellableResult.Cancelled // IDK... ) |> AsyncResult.fromAsync
}
错误类型不匹配。期待一个 任务&GT; - &GT; '但是给了一个 异步&LT;'c取代; - &GT;异步&GT;类型'任务&gt;'与“Async&lt; b&gt;”
类型不匹配
答案 0 :(得分:2)
对不起,这不一定是答案,但不适合作为评论。
您是否需要将取消令牌传递给您的工作流程?我认为使用Async.CancellationToken
传播工作流的现有令牌可能会更好:
async {
let! ct = Async.CancellationToken // gets the async workflow's current cancellation token
use receiveCommand = new SqlCommand(receiveQuery, connection, CommandTimeout = 0)
let! result = receiveCommand.ExecuteNonQueryAsync(ct) |> Async.AwaitTask
// do something with the result
}
通过将异步工作流程的取消令牌线程化到您关心的计算,您可以取消工作流程来做正确的事情 - 它可以在从一个步骤转换到另一个步骤时取消顶级工作流程,或者它可以取消查询执行是否正在执行。
然后,当您通过Async.RunSynchronously
或Async.Start
之类的方法计划您的异步时,如果您有,则可以传入现有的取消令牌。
然而,我并不完全清楚你是否真的想要这样做,因为你正在使用let rec
,但你没有表示需要递归逻辑。