2

私は次のような機能を持っています

   private void DoSomethingToFeed(IFeed feed)
   {
      feed.SendData(); // Send data to remote server
      Thread.Sleep(1000 * 60 * 5); // Sleep 5 minutes
      feed.GetResults(); // Get data from remote server after it's processed it
   }

互いに独立しているフィードがたくさんあるので、これを並列化したいです。この回答に基づいて、をそのままにThread.Sleep()しておくことはお勧めできません。また、すべてのスレッドがスピンアップした後、すべてのスレッドが結果を取得する機会を得るまで待ちたいと思います。

このようなシナリオを処理する最善の方法は何ですか?

誤って省略したため、編集します。もともとこの関数を として呼び出すことを検討していParallel.ForEach(feeds, DoSomethingToFeed)ましたが、リンク先の回答を見つけたときにスリープを処理するためのより良い方法があるかどうか疑問に思っていました。

4

4 に答える 4

3

Task.NETのクラスを確認する必要があると思います。これは、より低レベルのスレッド化/スレッド プール管理の上にある優れた抽象化です。

すべてのタスクが完了するのを待つために、 を使用できますTask.WaitAll

s の使用例はTask次のようになります。

IFeed feedOne = new SomeFeed();
IFeed feedTwo = new SomeFeed();

var t1 = Task.Factory.StartNew(() => { feedOne.SendData(); });

var t2 = Task.Factory.StartNew(() => { feedTwo.SendData(); });

// Waits for all provided tasks to finish execution
Task.WaitAll(t1, t2);

ただし、Parallel.ForEachすべてのTask作成を処理し、タスクの適切なバッチ処理も行う別のソリューションを使用することになります。ここでは、2 つのアプローチの適切な比較を示します。他の優れた点の中でも、次のことが述べられています。

Parallel.ForEach は、内部的に Partitioner を使用して、コレクションを作業項目に配布します。アイテムごとに 1 つのタスクを実行するのではなく、関連するオーバーヘッドを下げるためにこれをバッチ処理します。

于 2012-10-24T22:04:12.353 に答える
3

非常に多くのスレッドがない限り、シンプルに保つことができます。すべてのスレッドを作成します。スレッド作成のオーバーヘッドがいくらか発生しますが、スレッドは基本的にずっとスリープしているため、コンテキストの切り替えがあまり発生しません。

他のどのソリューションよりもコーディングが簡単です (C# 5 を使用している場合を除く)。それから始めて、実際にパフォーマンスの問題が発生した場合にのみ改善してください。

于 2012-10-24T22:22:04.837 に答える
1

タスクの待機については、 WaitHandleを確認してください。

于 2012-10-24T22:04:28.210 に答える
-1
private void DoSomethingToFeed(IFeed feed)
{
    Task.Factory.StartNew(() => feed.SendData())
        .ContinueWith(_ => Delay(1000 * 60 * 5)
                          .ContinueWith(__ => feed.GetResults())
                     );
}

//http://stevenhollidge.blogspot.com/2012/06/async-taskdelay.html
Task Delay(int milliseconds)      
{
    var tcs = new TaskCompletionSource<object>();
    new System.Threading.Timer(_ => tcs.SetResult(null)).Change(milliseconds, -1);
    return tcs.Task;
}
于 2012-10-24T22:35:05.677 に答える