.net - 带超时的 F# 异步工作流

标签 .net asynchronous f# timeout

我真的很喜欢 F# 的 async工作流,但对我来说,它有一个严重的问题:它不允许创建执行时间不超过某个特定时间跨度的工作流。

为了更清楚,这是我为自己编写的一个简单函数:

let withTimeout operation timeout = async {
    try
        return Some <| Async.RunSynchronously (operation, timeout)
    with :? TimeoutException -> return None
}

IE。签名是
val withTimeout : operation:Async<'a> -> timeout:int -> Async<'a option>

示例用法在这里:
let op = async { 
    do! Async.Sleep(1000) 
    return 1
}
#time
withTimeout op 2000 |> Async.RunSynchronously;;
// Real: 00:00:01.116, CPU: 00:00:00.015, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = Some 1
withTimeout op 2000 |> Async.RunSynchronously;;
// Real: 00:00:01.004, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = Some 1
withTimeout op 500 |> Async.RunSynchronously;;
// Real: 00:00:00.569, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
// val it : unit option = None    

你可以看到,它按预期工作。它非常好,但也有点尴尬,我不确定它的安全性和其他可能出现的问题。也许我正在重新发明轮子,并且有编写此类工作流程的简洁明了的方法?

最佳答案

请查看 this Async.WhenAny 的实现,它的行为应该类似于 Task.WhenAny .

通过使用它,您可以实现 withTimeout类似于 Task 的实现方式here :

let withTimeout dueTime comp =
    let success = async {
        let! x = comp
        return (Some x)
    }
    let timeout = async {
        do! Async.Delay(dueTime)
        return None
    }
    Async.WhenAny(success, timeout)

我不确定它会在第一个计算完成时取消另一个计算,但至少这个实现不会不必要地阻塞线程。

关于.net - 带超时的 F# 异步工作流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22245268/

相关文章:

java - 玩法2 异步Promise兑现

c# - 无法枚举 C# 中的 F# 列表列表

arrays - F# 使用非连续数字初始化数组

.net - 使用 Exchange Web 服务发送带有特殊字符的电子邮件

asp.net - 如何在.NET中正确将大写希腊语单词转换为大写?

c# - 如何反序列化或恢复未完成序列化的二进制序列化字典?

javascript - 异步如何处理 Javascript 中的变量?

python - 解决 Hettinger 示例的异步三重奏方法

c# - C# 中的 FSharpChoice

c# - 使用c#将数据导入Hadoop