29

Windows 7、Intel CORE i3、64 ビット、RAM 4Gb、2.27 GHz
.NET Framework 4.0

次のコードがあります。

static void Main(string[] args)
{
    var timer = new Stopwatch();
    timer.Start();

    for (int i = 0; i < 0xFFF; ++i)
    {
        // I use one of the following line at time
        Task.Factory.StartNew(() => { });
        new Thread(() => { }).Start();
    }

    timer.Stop();

    Console.WriteLine(timer.Elapsed.TotalSeconds);
    Console.ReadLine();
}

Task を使用すると、出力は常に0.01 秒未満になりますが、Thread を使用すると、出力は常に40 秒を超えます。
それはどのように可能ですか?なぜそんなに違いがあるのですか?

4

6 に答える 6

37

2つは同じではありません。

を使用するTask.Factory.StartNewと、 で実行するタスクをスケジュールしますThreadPool。新しい を作成するときThreadは、新しいスレッドを作成して開始する必要があります。

最初のケースでは、スレッドはすでに作成され、再利用されています。これにより、反復ごとにスレッドを作成する必要がないため、タスクのスケジューリングのオーバーヘッドがはるかに低くなります。

ただし、動作は同じではないことに注意してください。個別のスレッドを作成すると、各タスクは独自のスレッドを取得します。それらはすべてすぐに開始されます。を使用する場合Task.Factory.StartNew、それらは で実行するためにスケジューラに入れられます。ThreadPoolこれにより、開始される同時スレッドの数が (潜在的に) 制限されます。これは、オーバースレッドの発生を防ぐため、通常は良いことです。

于 2012-10-29T15:56:37.277 に答える
4

を開始するたびTaskに、多数のスレッドによって処理されるプールに入ります。その多くは事前に作成されている可能性があります。M:Nプール内のスレッドに対するタスクの比率があります。

を開始するたびThreadに、新しいスレッドが作成され、スレッドの作成に関連するすべてのオーバーヘッドが発生します。スレッドを明示的に作成しているため、スレッドの比率は 1:1 です。

タスクとスレッドの比率が 1 に近づくほど、タスクの起動が「遅く」なります。実際にThreadPoolは、比率が 1 よりもはるかに高いままであることを保証します。

于 2012-10-29T15:57:06.780 に答える
1

各スレッド/タスクが終了するのを待たないという点で、テストに問題があります。

タスクはキューを使用するため、スレッドよりもタスクを作成する方がはるかに高速です。

タスク/スレッドが終了するのを待っていたとしても、タスクを使用した方が速いことは間違いありません。スレッドの作成と破棄のオーバーヘッドは高くなります。それが Task.Factory が作成された理由です!

于 2012-10-29T16:01:47.440 に答える
0

Task.Factory.StartNew()タスクをすぐに開始するのではなく、タスクをスケジュールするだけなので、TaskScheduled は少し後で開始できます (使用可能なスレッド/タスクの数によって異なります)。

MSDN は、Thread.Start()オペレーティング システムが実行をスケジュールできるようになった後、OS との対話は .NET Framework の TaskScheduler よりもはるかに遅くなりますが、それほどではないと述べています。

例に戻ると、0xFFF == 4095 であるため、4095 スレッドをスケジュールしており、これには 40 秒かかります。1 秒間に 102 スレッドというのは、かなりのタイミングです。:)

于 2012-10-29T15:56:56.310 に答える
0

呼び出しTask.Factory.StartNewによって必ずしも新しいスレッドが作成されるとは限りません。それらはTaskScheduler、コードを実行しているマシンのコア数などに基づいて管理されます。

同時に実行できるよりも多くのタスクを ( を呼び出してTask.Factory.StartNew) スケジュールすると、より多くのリソースが使用可能になると、それらのタスクはキューに入れられて実行されます。

于 2012-10-29T15:58:45.243 に答える
0

新しいスレッドの作成は遅いですが、それほど遅くはありません。Nick は ~10ms/スレッドを報告しました。ほとんどの場合、Visual Studio デバッガーで発生しました。Visual Studio デバッガーで、新しいスレッドごとに ~3.9ms を取得しています。デバッガーなしで、新しいスレッドごとに約 0.15 ミリ秒を取得しています。

http://dennisgorelik.livejournal.com/125269.html?thread=2238805#t2238805

于 2017-02-06T20:10:49.150 に答える