Task Parallel Library (Task and Future continuation chain) を多用して、並行コードを実行する c# で書かれたものがあります。
私は現在、これを F# に移植しており、F# Async ワークフローと TPL のコンストラクトを使用することの長所と短所を理解しようとしています。私はTPLに傾いていますが、どちらの方法でも可能だと思います。
F# で並行プログラムを作成する際のヒントや知恵を共有できる人はいますか?
Task Parallel Library (Task and Future continuation chain) を多用して、並行コードを実行する c# で書かれたものがあります。
私は現在、これを F# に移植しており、F# Async ワークフローと TPL のコンストラクトを使用することの長所と短所を理解しようとしています。私はTPLに傾いていますが、どちらの方法でも可能だと思います。
F# で並行プログラムを作成する際のヒントや知恵を共有できる人はいますか?
この名前は、非同期プログラミングと並列プログラミングの違いをほぼ要約しています。しかし、F#では、組み合わせることができます。
F#非同期ワークフローは、コードを非同期で実行する場合、つまりタスクを開始し、最終結果を待たない場合に役立ちます。これの最も一般的な使用法はIO操作です。スレッドをアイドルループに置いて、ハードディスクの書き込みが完了するのを待つと、リソースが無駄になります。
書き込み操作を非同期で開始した場合は、スレッドを一時停止して、後でハードウェア割り込みによってウェイクアップさせることができます。
.NET 4.0のタスク並列ライブラリは、MP3のデコードや、データベースからの結果の読み取りなど、タスクの概念を抽象化します。これらの状況では、実際に計算の結果が必要であり、ある時点で操作の結果を待っています。(.Resultプロパティにアクセスすることによって。)
これらの概念を簡単に組み合わせることができます。TPLタスクオブジェクトですべてのIO操作を実行するなど。プログラマーにとって、あなたはその余分なスレッドに「対処する」必要性を抽象化しましたが、隠れてあなたはリソースを浪費しています。
同様に、一連のF#非同期ワークフローを作成して並列に実行することもできますが(Async.Parallel)、最終結果を待つ必要があります(Async.RunSynchronously)。これにより、すべてのタスクを明示的に開始する必要がなくなりますが、実際には、計算を並行して実行しているだけです。
私の経験では、通常はN個の操作を並行して実行したいので、TPLの方が便利であることがわかりました。ただし、F#非同期ワークフローは、リアクティブエージェントやメールボックスタイプのものなど、「舞台裏」で起こっていることがある場合に理想的です。(メッセージを送信すると、メッセージが処理されて返送されます。)
お役に立てば幸いです。
4.0 では、次のように言います。
ミックス&マッチも可能です。ワークフローをタスクとして実行し、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 の両方が追加のカーネル プリミティブ (イベント) を作成し、完了ポートとコールバックを使用するのではなく、WaitForMultipleObjectsを使用して I/O 完了を追跡することにも注意してください。これは、一部のアプリケーションでは望ましくありません。