0

私は以下のコードを持っています:

class Program
{
    static void Main(string[] args)
    {

        Task[] tasks = new Task[3]
                        {
                            Task.Factory.StartNew(() => Console.WriteLine("Hello A")),
                            Task.Factory.StartNew(() => Console.WriteLine("Hello B")),
                            Task.Factory.StartNew(() => Console.WriteLine("Hello C"))
                        };
        Task.WaitAll(tasks); 
        Console.WriteLine("Hi ABC");
    }
}

上記のコードをビルドして実行すると、次の出力が得られます
。Hello C
Hello B
Hello A
Hi ABC

しかし、Task.WaitAll(tasks)にコメントすると、出力の1つは次のようになります。HiABC
Hello
B
Hello C

Console.WriteLine( "Hi ABC")が実行を終了したときに、Console.WriteLine( "Hello A")を実行するスレッドが実行を終了する機会がなかったことを意味しますか?

4

5 に答える 5

4

それは正解です。子スレッドが終了する前に、または場合によっては開始する前に、メインスレッドがプロセスを終了しています。メイン スレッドをビジー状態に保つために何もしないと、メイン スレッドが終了したとき ("Hi ABC" の後)、プロセスの終了によってすべての未処理のスレッドが強制終了されます。A スレッド (またはいずれかの子スレッド) がまだスケジュールされていない場合、出力する機会はまったくありません。

于 2012-06-15T21:03:41.620 に答える
2

タスクを待たなければ、4 つのスレッド (3 つのタスクとメイン スレッド) がすべて同時に実行されます。

メイン スレッドは起動する必要がないため、最初に print ステートメントに到達する可能性があります。

于 2012-06-15T21:02:51.750 に答える
2

これは、スレッドが終了するか、プログラムの終了後にスレッドが強制終了されたことを意味します。Console.ReadLine(); を追加する必要があります。手動で待機すると、それらがすべて終了することがわかります。

于 2012-06-15T21:03:48.200 に答える
1

がなければWaitAll、実行は通常どおり続行されます。最後の の後Console.WriteLine、プログラムの最後に達したため、アプリケーションは終了します。

于 2012-06-15T21:03:57.393 に答える
0

ここにあるのは、「競合状態」として知られているものです。つまり、 、Hello AHello BHello Cおよびの順序Hi ABCは任意であり、どのスレッドが最初に終了するかによって変わる可能性があります。したがって、実行が異なれば、異なる結果が得られる可能性があります。

何が起こっているかというと、これらのスレッドをスピンオフしてから、プログラムの実行を継続しているということです。この場合、競合状態は、メイン実行スレッドが終了する (プログラムの終了) ときに強制終了される前に、どのスレッドが出力を出力できるかということです。メイン スレッドからの出力が最初になるとは限りませんが、開始からのオーバーヘッドが少ないため、最初になる可能性があります。Task.WaitAllを aに変更することでこれをテストSystem.Threading.Thread.Sleep(200)し、メソッドに渡すミリ秒を変更すると出力がどうなるかを確認できますSleep

待機せずに、メインスレッドは、子スレッドがどのような状態にあるかに関係なく、子スレッドを強制終了します。あなたが言及した場合、スレッド B と C はConsole.WriteLine('Hi ABC')プログラムの最後まで完了していました。スレッド A は終了しなかったため、出力する前に強制終了されました。

于 2012-06-15T21:10:17.787 に答える