asynchronous - 在 F# 中运行超时的 IO 任务
问题描述
我正在尝试与 F# 中的云服务交谈,并在这些操作周围出现超时。
现在这是多次迭代,但我仍然无法弄清楚如何使用 Async。
let tokenSource = new CancellationTokenSource()
let task = Async.StartAsTask(async {return (getS3Meta keyMeta)}, TaskCreationOptions.None, tokenSource.Token)
let metaMaybe = Async.AwaitTask(task, 700) |> Async.RunSynchronously
为了支持我们引入的超时:
type Timeout = Timeout
type Microsoft.FSharp.Control.Async with
static member AwaitTask (t : Task<'T>, timeout : int) =
async {
use cts = new CancellationTokenSource()
use timer = Task.Delay (timeout, cts.Token)
let! completed = Async.AwaitTask <| Task.WhenAny(t, timer)
if completed = (t :> Task) then
cts.Cancel ()
let! result = Async.AwaitTask t
return Ok result
else return Error Timeout
}
无论我做什么,任务总是在 WaitingForActivation 中。
IO操作超时的推荐方式是什么,它可以阻止主执行,我这里不需要异步代码。如果我必须使用异步,那么用于启动超时任务的原语是什么?
解决方案
当前工作的代码(即使我们不了解与不同异步工作流相关的不同权衡,我们也没有遇到问题)。
let doSomeIoAsync =
async {
return (anotherAsyncWokFlowIoInCsharpLib someParam)
}
let task = Async.StartAsTask doSomeIoAsync
match task.Wait(500) with
| true -> Success task.Result
| false -> Error Timeout
一些fsi:
> let ioFn () = Thread.Sleep(5000); System.Console.WriteLine 100; 100;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val ioFn : unit -> int
> ioFn();;
100
Real: 00:00:05.005, CPU: 00:00:00.001, GC gen0: 0, gen1: 0, gen2: 0
val it : int = 100
> let taskAsync = async { return ioFn() };;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val taskAsync : Async<int>
> let t = Async.StartAsTask taskAsync ;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val t : Tasks.Task<int>
> t.Wait(500) ; t.Status;;
Real: 00:00:00.505, CPU: 00:00:00.001, GC gen0: 0, gen1: 0, gen2: 0
val it : Tasks.TaskStatus = WaitingForActivation
> 100
- t.Wait(500) ; t.Status;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : Tasks.TaskStatus = RanToCompletion
> t.Result;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : int = 100
我认为这样使用 WaitingForActivation 有点误导。也许我误解了它,它真的是 WaitingForCompletion。
就性能而言,前几个请求与其余请求相比非常慢:
Error: WaitingForActivation
Elapsed Time: 296
Error: WaitingForActivation
Elapsed Time: 254
Error: WaitingForActivation
Elapsed Time: 255
Error: WaitingForActivation
Elapsed Time: 254
Error: WaitingForActivation
Elapsed Time: 254
OK: RanToCompletion
Elapsed Time: 249
OK: RanToCompletion
Elapsed Time: 147
OK: RanToCompletion
Elapsed Time: 246
OK: RanToCompletion
Elapsed Time: 146
OK: RanToCompletion
Elapsed Time: 150
OK: RanToCompletion
Elapsed Time: 142
OK: RanToCompletion
Elapsed Time: 143
OK: RanToCompletion
Elapsed Time: 139
OK: RanToCompletion
Elapsed Time: 139
OK: RanToCompletion
Elapsed Time: 141
不知道如何摆脱缓慢的启动。
推荐阅读
- c++ - 限制第一人称相机的俯仰旋转c ++ ue4
- node.js - 除非节点版本不同,否则节点应用程序无法在端口 80 上启动
- reactjs - onChange 时 React Select 不触发
- assembly - 如何将结果总和值存储到内存 RISC-V
- convex-optimization - 如何判断函数是非凸的还是凸的
- python - Response.url 和引用 url scrapy
- c# - 如何在 PDB 中嵌入 C# 源代码进行调试?
- spring-boot - Spring-boot BOM 不包含对 tomcat-dbcp 的依赖项
- javascript - 多余的if语句?
- grafana - 如何从其他唯一标签中计算标签