質問

タスク並列ライブラリ (タスクおよび将来の継続チェーン) を多用して、同時コードを実行するものを C# で作成しました。

私は現在これを F# に移植しており、F# 非同期ワークフローを使用する場合と、F# 非同期ワークフローを使用する場合の長所と短所を理解しようとしています。TPL 内の構成。私は TPL に傾いていますが、どちらの方法でも実行できると思います。

F# での同時実行プログラムの作成に関するヒントや知恵を共有できる人はいますか?

役に立ちましたか?

解決

名前はその違いをほぼ要約しています。 非同期 プログラミング vs. 平行 プログラミング。しかし、F# では組み合わせて使用​​できます。

F# 非同期ワークフロー

F# 非同期ワークフローは、コードを非同期で実行する場合、つまりタスクを開始して最終結果を待たない場合に役立ちます。これの最も一般的な使用法は IO 操作です。ハードディスクの書き込みが完了するまでスレッドをアイドル ループに待機させると、リソースが無駄になります。

書き込み操作を非同期で開始した場合は、スレッドを一時停止し、後でハードウェア割り込みによってスレッドをウェイクアップさせることができます。

タスク並列ライブラリ

.NET 4.0 のタスク並列ライブラリは、MP3 のデコードやデータベースからの結果の読み取りなど、タスクの概念を抽象化します。このような状況では、実際には計算の結果が必要であり、その後のある時点で操作の結果を待っていることになります。(.Result プロパティにアクセスすることにより。)

これらの概念を簡単に組み合わせて組み合わせることができます。たとえば、すべての IO 操作を TPL タスク オブジェクトで実行します。プログラマに対しては、余分なスレッドを「処理する」必要性を抽象化していますが、隠れたところではリソースを無駄にしていることになります。

同様に、一連の F# 非同期ワークフローを作成して並列実行することもできますが (Async.Parallel)、最終結果を待つ必要があります (Async.RunSynchronously)。これにより、すべてのタスクを明示的に開始する必要がなくなりますが、実際には計算を並行して実行しているだけです。

私の経験では、通常は N 個の操作を並行して実行したいため、TPL の方が便利であることがわかりました。ただし、F# 非同期ワークフローは、Reactive Agent や Mailbox タイプのものなど、「舞台裏」で進行しているものがある場合に最適です。(メッセージを送信すると、それが処理されて送り返されます。)

それが役立つことを願っています。

他のヒント

4.0 では次のように言えます。

  • 関数がシーケンシャルである場合は、非同期ワークフローを使用します。彼らは単純に読書が上手です。
  • それ以外のすべてには TPL を使用してください。

組み合わせて使用​​することも可能です。ワークフローをタスクとして実行し、非同期の開始/終了パターンに従うタスクを作成するためのサポートが追加されました。 TaskFactory.FromAsync, 、TPL に相当するもの Async.FromBeginEnd または Async.BuildPrimitive.

let func() =
    let file = File.OpenRead("foo")
    let buffer = Array.zeroCreate 1024
    let task1 = Task.Factory.FromAsync(file.BeginRead(buffer, 0, buffer.Length, null, null), file.EndRead)
    task1.Start()

    let task2 = Async.StartAsTask(file.AsyncRead(1024))
    printfn "%d" task2.Result.Length

非同期ワークフロー ランタイムと TPL の両方が追加のカーネル プリミティブ (イベント) を作成し、 複数のオブジェクトを待つ 完了ポートやコールバックを使用するのではなく、I/O の完了を追跡します。これは一部のアプリケーションでは望ましくないことです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top