gpt4 book ai didi

asynchronous - 等待取消异步工作流

转载 作者:行者123 更新时间:2023-12-04 23:26:50 26 4
gpt4 key购买 nike

Cancel CancellationTokenSource 的成员对象“传达取消请求”,我认为这意味着它是触发并忘记并且不会等到取消完成(例如,所有异常处理程序都已运行)。这很好,但我需要等到一个未完成的异步完全取消后再创建另一个异步。有没有简单的方法来实现这一点?

最佳答案

我认为没有任何直接的方法可以使用 F# 异步库中的标准库函数来做到这一点。最近的操作我们Async.TryCancelled当工作流(实际上)取消时运行回调,但是必须手动将消息从回调发送到启动工作流的代码。

使用事件和我编写的 F# 异步扩展(也包含在 FSharpX 包中)的扩展相对容易解决 - 扩展是 GuardedAwaitObservable可用于等待事件的发生(可以通过某些操作立即触发)。

以下Async.StartCancellable方法采用异步工作流并返回 Async<Async<unit>> .当您在外部工作流程上绑定(bind)时,它会启动参数(如 Async.StartChild ),当您在返回的内部工作流程上绑定(bind)时,它会取消计算并等待直到实际取消:

open System.Threading

module Async =
/// Returns an asynchronous workflow 'Async<Async<unit>>'. When called
/// using 'let!', it starts the workflow provided as an argument and returns
/// a token that can be used to cancel the started work - this is an
/// (asynchronously) blocking operation that waits until the workflow
/// is actually cancelled
let StartCancellable work = async {
let cts = new CancellationTokenSource()
// Creates an event used for notification
let evt = new Event<_>()
// Wrap the workflow with TryCancelled and notify when cancelled
Async.Start(Async.TryCancelled(work, ignore >> evt.Trigger), cts.Token)
// Return a workflow that waits for 'evt' and triggers 'Cancel'
// after it attaches the event handler (to avoid missing event occurrence)
let waitForCancel = Async.GuardedAwaitObservable evt.Publish cts.Cancel
return async.TryFinally(waitForCancel, cts.Dispose) }

编辑 将结果包装在 TryFinally 中处置 CancellationTokenSource正如乔恩所建议的那样。我认为这应该足以确保它被正确处理。

这是使用该方法的示例。 loop函数是我用于测试的简单工作流程。其余代码启动它,等待 5.5 秒然后取消它:
/// Sample workflow that repeatedly starts and stops long running operation
let loop = async {
for i in 0 .. 9999 do
printfn "Starting: %d" i
do! Async.Sleep(1000)
printfn "Done: %d" i }

// Start the 'loop' workflow, wait for 5.5 seconds and then
// cancel it and wait until it finishes current operation
async { let! cancelToken = Async.StartCancellable(loop)
printfn "started"
do! Async.Sleep(5500)
printfn "cancelling"
do! cancelToken
printfn "done" }
|> Async.Start

为完整起见,具有 FSharpX 必要定义的示例为 here on F# snippets .

关于asynchronous - 等待取消异步工作流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11609089/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com