15

假设asyncSendMsg不返回任何内容并且我想在另一个异步块中启动它,但不等待它完成,这之间有什么区别:

async {
    //(...async stuff...)
    for msg in msgs do 
        asyncSendMsg msg |> Async.Start
    //(...more async stuff...)
}

async {
    //(...async stuff...)
    for msg in msgs do 
        let! child = asyncSendMsg msg |> Async.StartChild
        ()
    //(...more async stuff...)
}
4

1 回答 1

24

主要区别在于,当您使用 启动工作流时Async.StartChild,它将与父级共享取消令牌。如果取消父级,所有子级也将被取消。如果您使用 启动孩子Async.Start,那么它是一个完全独立的工作流程。

这是一个演示差异的最小示例:

// Wait 2 seconds and then print 'finished'
let work i = async {
  do! Async.Sleep(2000)
  printfn "work finished %d" i }

let main = async { 
    for i in 0 .. 5 do
      // (1) Start an independent async workflow:
      work i |> Async.Start
      // (2) Start the workflow as a child computation:
      do! work i |> Async.StartChild |> Async.Ignore 
  }

// Start the computation, wait 1 second and than cancel it
let cts = new System.Threading.CancellationTokenSource()
Async.Start(main, cts.Token)
System.Threading.Thread.Sleep(1000)    
cts.Cancel()

在此示例中,如果您使用 开始计算(1),则所有工作项将在 2 秒后完成并打印。如果您使用(2)它们,它们将在主工作流程取消时全部取消。

于 2013-03-08T00:02:32.197 回答