2

させてくれた印象でした!in f#は、一連の割り当てを並行して実行するのに十分なほどスマートでした。ただし、次のサンプルは異なる動作を示しており、a、b、cの割り当ては同期して実行されているようです。

    let sleep sec =
        async
            {
                System.Threading.Thread.Sleep(sec * 1000)
                return sec
            }

    let bar = async 
                {
                    let! a = sleep 1
                    let! b = sleep 3
                    let! c = sleep 3
                    return a+b+c
                }

    let foo = Async.RunSynchronously(bar)
    printfn "%d" foo

それはどうあるべきか/あるべきか?

そして、a、b、cを並行して実行したい場合、Async.Parallell ... |> Async.RunSynchronously ...を使用することになっていますか?

上記のサンプルはもちろん役に立ちません。実際のユースケースは、DBにクエリを実行し、同時にいくつかのWebサービスを呼び出すようなものです。

4

2 に答える 2

7

リチャードが指摘するように、非同期ワークフローはまだ完全にシーケンシャルです。完全自動並列化を試みるプロジェクトは、それを行うのが非常に難しいため、完全に成功したとは思いません。

ただし、非同期ワークフローを使用すると、並列化が容易になります。重要なのは、スレッドをブロックせずに待機できることです(これはスケーラビリティに不可欠です)。また、自動キャンセルと簡単な例外処理をサポートして、作業を楽にします。非同期ワークフローでコードを並列化できるようにするさまざまなパターンがあります。

  • タスクベースでは、3つのタスクをバックグラウンドで開始し、すべてが完了するまで待つことができます(これはおそらく期待していたことなので、明示的に記述する方法は次のとおりです)。

    let bar = async  { 
      let! atask = sleep 1 |> Async.StartChild
      let! btask = sleep 3 |> Async.StartChild
      let! ctask = sleep 3 |> Async.StartChild
      let! a = atask
      let! b = btask
      let! c = ctask
      return a + b + c } 
    
  • データ並列-同じタイプのワークフローが複数ある場合は、を使用してそれらすべてを並列に実行するワークフローを作成できますAsync.Parallel。次に使用するlet!と、3つのタスクすべてが実行され、完了するまで待機します。

    let bar = async  { 
      let! all = Async.Parallel [ sleep 1; sleep 3; sleep 3 ]
      return all.[0] + all.[1] + all.[2] } 
    

Don Symeには、非同期ワークフローに基づくさまざまなパターンについて説明している記事があり、財務ダッシュボードのサンプルで包括的な例を見つけることができます。

于 2010-10-04T12:05:03.313 に答える
2

let!asyncブロック内(より正確には「計算式」)は式を非同期で実行しますが、ブロック全体は依然として線形に実行されます。これは、async計算式の利点です。継続渡しを実行することで、依存する非同期操作のシーケンスをはるかに簡単に記述できるようになります。

let!(他のタイプの計算式は、、などに独自のセマンティクスを提供しますyield!。)

並列/並行実行を実行するには、複数のasync式を別々に実行する必要があります。

印象に残った

あなたは誤解しました(かなり当然のことながら)。

于 2010-10-04T08:06:45.213 に答える