6

私は読んC# 5.0 in nutshellでいましたが、著者の見解を読んだ後、何を採用すべきかについてかなり混乱しています。私の要件は、たとえば、何百万ものファイルのSHA1(またはその他の)ハッシュを計算するなど、非常に長時間実行される(計算量が多い)タスクがあると言うか、実際には他のことは計算量が多く、時間がかかる可能性があることです、それを開発するための私のアプローチはどうあるべきですか(winformsそれが重要な場合は、VS 2012、C#5.0を使用して)so that I can also report progress to the user、.

次のシナリオが思い浮かびます...

  1. ハッシュを計算し、タスクを実装する、またはタスクにコンテキストをキャプチャさせて UI に投稿させることにより、進行状況をユーザーに報告するオプションを使用してTask作成します。LongRunningIProgess<T>Progess<T> SynchronizationContext

  2. Asyncのようなメソッドを作成します。

     async CalculateHashesAsync() 
     {
         // await here for tasks the calculate the hash
         await Task.Rung(() => CalculateHash();
        // how do I report progress???
     }
    
  3. TPL (または PLINQ) を次のように使用します。

    void CalcuateHashes()  
    {  
        Parallel.For(0, allFiles.Count, file => calcHash(file)    
        // how do I report progress here?   
    }
    
  4. プロデューサー/コンシューマー キューを使用します。
    本当に方法がわからないのですか?

本の著者は言う...

プールされたスレッドで実行時間の長いタスクを1 つ実行しても、問題は発生しません。複数の長時間実行タスク (特にブロックするタスク) を並行して実行すると、パフォーマンスが低下する可能性があります。その場合、通常、TaskCreationOptions.LongRunnging よりも優れたソリューションがあります。

  • タスクが IO バウンドの場合、TaskCompletionSource と非同期関数を使用すると、スレッドではなくコールバックを使用して同時実行を実装できます。
  • タスクがコンピューティング バウンドの場合、プロデューサー/コンシューマー キューを使用すると、それらのタスクの同時実行性を調整して、他のスレッドやプロセスの枯渇を回避できます。

Producer/Consumer著者の言うことについて...

プロデューサー/コンシューマー キューは、一度に実行するワーカー スレッドの数を正確に制御できるため、並列プログラミングと一般的な同時実行シナリオの両方で便利な構造です。これは、CPU 消費を制限するだけでなく、他のリソースにも役立ちます。

では、タスクを使用しないでください。つまり、最初のオプションはありませんか? 2番目が最良の選択肢ですか?他のオプションはありますか?そして、著者のアドバイスに従い、プロデューサー/コンシューマーを実装する場合、どうすればよいでしょうか (それが最善のアプローチである場合、私のシナリオでプロデューサー/コンシューマーを開始する方法さえわかりません! )

誰かがそのようなシナリオに遭遇したことがあるかどうか知りたいのですが、どのように実装しますか? そうでない場合、最もパフォーマンスが高く、かつ/または開発/保守が容易なものは何でしょうか (言葉performanceが主観的であることは知っていますが、それが機能し、うまく機能するという非常に一般的なケースを考えてみましょう!)

4

1 に答える 1