2

async1 を構成してから async2を構成するための言語にプリミティブはありますか?

さらに明確にするために、2 つの非同期計算があります。

  let toto1 = Async.Sleep(1000)
  let toto2 = Async.Sleep(1000)

toto1 と toto2 の逐次構成からなる新しい非同期計算を作成したい

  let toto = Async.Sequential [|toto1; toto2|]

開始時に、toto は toto1 を実行してから toto2 を実行し、2000 時間単位後に終了します。

4

2 に答える 2

4

async.Bind操作は、非同期ワークフローが順次構成のために提供する基本的なプリミティブです。asyncブロック構文では、 に対応しlet!ます。これを使用して、2 つの計算の連続合成を表現できます (Daniel が示しているように)。

ただし、Daniel が定義した操作がある場合、それはを実装するのに<|>十分な表現力がありません。使用することができます:async.Bindasync.Bind<e2>v1

async.Bind(<e1>, fun v1 -> <e2>)

書いていた<e1> <|> <e2>場合、2 つの操作は独立している必要があります。これが、ライブラリが に基づいている理由です。これはBindAsync.Parallel.

のように動作Async.Parallelし、配列を取るものが必要な場合、最も簡単なオプションはlet!、ループ内で命令的に使用して実装することです (ただし、再帰とリストも使用できます)。

let Sequential (ops:Async<'T>[]) = async {
  let res = Array.zeroCreate ops.Length
  for i in 0 .. ops.Length - 1 do
    let! value = ops.[i]
    res.[i] <- value 
  return res }
于 2012-03-08T21:17:10.637 に答える
2

「プリミティブ」の意味がわかりません。Async.Parallel関数です。2 つの非同期を実行するいくつかの方法を次に示します。

並行して:

Async.Parallel([|async1; async2|])

また

async {
  let! child = Async.StartChild async2
  let! result1 = child
  let! result2 = async1
  return [|result1; result2|]
}

順次:

async {
  let! result1 = async1
  let! result2 = async2
  return [|result1; result2|]
}

最後の 2 つでタプルを返すことができます。戻り値の型は最初のものと同じにしました。

私は、これにプリミティブを使用するのと同じくらい近いブロックであるlet!と言います。do!async { }

編集

この厄介な構文がすべてあなたに届いている場合は、コンビネーターを定義できます。

let (<|>) async1 async2 = 
  async {
    let! r1 = async1
    let! r2 = async2
    return r1, r2
  }

そして、次のようにします。

async1 <|> async2 |> Async.RunSynchronously
于 2012-03-08T16:36:09.897 に答える