如何在异步计算表达式中编写Task.ContinueWith

时间:2017-03-31 19:41:43

标签: f# task-parallel-library

我正在努力弄清楚如何在异步计算表达式中编写 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;”

类型不匹配

1 个答案:

答案 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.RunSynchronouslyAsync.Start之类的方法计划您的异步时,如果您有,则可以传入现有的取消令牌。

然而,我并不完全清楚你是否真的想要这样做,因为你正在使用let rec,但你没有表示需要递归逻辑。