4

キューに入れられたコールバックの順序が決定論的ではないことに気付きThreadPool.QueueUserWorkItemました.コールバックが渡された順序ではないことは確かです.

これは、次の簡単なプログラムで確認できます。

    private static void Main()
    {
        for (var i = 0; i < 10; ++i)
            ThreadPool.QueueUserWorkItem(Console.Write, i + " ");

        Thread.Sleep(1000);
    }

1 回の実行の出力は次のとおりです。

0 3 8 9 1 2 5 4 6 7

名前は、順序が保持されていることを示しています。

順序が保持されていることを確認する方法はありますか?
そうでない場合、どの代替実装を提案しますか?

4

4 に答える 4

6

順序を維持する方法はありません。スレッド プールの目的は、独立したタスクを並行して実行することです。これらのタスクが開始および終了する順序は、その性質上、非常に非決定的です。サブタスクを特定の順序で開始および終了する必要がある場合、それらを並列化することはできません。

private static void Main()
{
    for (var i = 0; i < 10; ++i)
        Console.Write(i + " ");

    Thread.Sleep(1000);
}

明確にするために、スレッドプールキュー内のタスクの順序は保持されますが、実際に実行される順序は非決定的です。

于 2013-01-24T16:25:36.087 に答える
6

タスクをシリアルに実行するが、呼び出しスレッドとは異なるスレッドで実行する場合は、Reactive ExtensionsのEventLoopSchedulerを調べる必要があります。これにより、特定のワーカー スレッドで作業単位をスケジュールできます。

于 2013-01-24T16:30:12.150 に答える
4

タスクの開始順序が保持されているかどうかはわかりません。ただし、キューに入れられたすべての作業項目は非同期で実行されるため、実行の順序を保証することはできません。

順序を維持したい場合、1 つのオプションは、スレッド プールからではなく、作業項目を連続して実行することです。もう 1 つは、最初のジョブで 2 番目のジョブをスケジュールすることです。さらに別の方法は、待機ハンドルを使用して作業を同期することです。

于 2013-01-24T16:26:25.430 に答える
1

名前は、順序が保持されていることを示しています。

名前の「キュー」は、スレッドプールスレッドで実行のためにキューに入れられたアイテムを意味します..つまり、スレッドプールスレッドが1つを除いてすべてビジーだった場合、アイテムは順番に1つずつキューに入れられますあなたはそれらをキューに入れました。ただし、アイテムが最初に利用可能なバックグラウンド スレッドに送られ、次に同時に実行される可能性は低いためです。

于 2013-02-02T04:43:59.240 に答える