asynchronous - 如何通过超时停止等待 TaskCompletionSource 周围的异步包装器?

标签 asynchronous f# task-parallel-library

假设我有一些无法更改的系统“BlackBox”,并且我想尝试用它做一些工作 2 秒钟,如果它无法完成 - 停止并继续其他应用程序:

let log msg =
    let timestamp = (System.DateTime.UtcNow.ToString("o"))
    printfn "%s: %s" timestamp msg

type BlackBox() =
    let tcs = new System.Threading.Tasks.TaskCompletionSource<bool>()

    let work () = async {
        log "work started"
        let! result = tcs.Task |> Async.AwaitTask
        log "work finished"
        return result }

    member x.DoWork    () = work ()
    member x.SetResult () = tcs.TrySetResult(true)

let tryDoWork (box:BlackBox) = async {
    try
        log "operration starting with 2sec timeout"
        Async.RunSynchronously(box.DoWork(), timeout = 2000) |> ignore
        log "operration succeeded"
    with
    | ex -> log "operation timedout" }

let sut = BlackBox()
tryDoWork sut |> Async.Start
log "waiting 5sec before setting task result"
Async.Sleep 5000 |> Async.RunSynchronously
log "setting task result"
sut.SetResult() |> ignore
​
​
// Output is:
// ------------------------------------
// 2016-02-24T16:45:11.0302884Z: waiting 5sec before setting task result
// 2016-02-24T16:45:11.0302884Z: operration starting with 2sec timeout
// 2016-02-24T16:45:11.0351932Z: work started
// 2016-02-24T16:45:16.0322394Z: setting task result
// 2016-02-24T16:45:16.0351731Z: work finished
// 2016-02-24T16:45:16.0361528Z: operation timedout

Async.RunSyncronously 超时会在 2 秒后抛出 TimeoutException,但在这种情况下不会,因为 BlackBox 内部正在等待任务完成。

最佳答案

TCS(来自 @Carsten 的评论)适合我,因为我无法访问 BlackBox 内部结构,并且无法在不更改应用程序的整个设计的情况下更改它,并且需要添加超时机制,不需要取消较长的任务

其他提议的事情是:

@凯文:

snippet by Eirik Tsarpalis and Async.AwaitIAsyncResult

@kevin 注意到我的示例未按预期工作的原因是

RunSynchronously with a timeout relies on the given async being cancelable

我发现的另一件事是 how to cancel non-cancelable async operations

关于asynchronous - 如何通过超时停止等待 TaskCompletionSource 周围的异步包装器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35608947/

相关文章:

f# - 匹配列表的前两个元素

c#-4.0 - 限制正在进行的流式资源并行操作的工作

c# - 带有 TaskCompletionSource 的 TaskCreationOptions 的目的是什么?

python - 这两种基于生成器的协程是同一个概念吗?

c# - 在 Dispatcher.RunAsync() 中使用 "await"会引发异常

f# - 无法使用带有 F# (FSharp) 的 OpenXml 附加工作表

c# - 任务中的异步套接字操作

javascript - 如何为 angularjs 站点设置诺顿密封?

javascript - 在 Web Worker 仍在运行时向其发送消息

内部函数的 F# 泛型