0

コンソールアプリケーション(これがそれと関係があるかどうかわからない)とタスクの使用で奇妙な問題が発生しています。

ほとんどの例は、WaitAllの概念をテスト/説明するために意図的に例外を呼び出すことを示していますが、私の場合、根本的に間違っている(または完全に理解していない)ようです。

Task<int> task1 = Task<int>.Factory.StartNew(()=> foo(arg));
Task<int> task2 = Task<int>.Factory.StartNew(()=> bar(arg));

Task<int>[] tasks = {task1, task2};

try
{
    Task.WaitAll(tasks); //hits this far

     if((int)task1.Result * (int)task2.Result == 99) //this seems to never get hit
     {
         System.Environment.Exit(0); //so this isn't called             
     }
     else
     {
         System.Environment.Exit(1); // neither is this called
     }
 }
 catch
 {
     .....

上記では、ifブロックがヒットしていないように見えるため、どちらの終了コードも返されません。したがって、コンソールアプリがハングします。

例外もスローされません-すべてのタスクが実際に完了しているため、これを確認できます-catch簡潔にするために、上記のセクションは含めませんでした。

タスクはすぐに完了します-ぶら下がっていないので、Task.WaitAllがまだ待機しているかのようではありません-またはおそらくそれは私が見逃しているものです(何を待っていますか)?

何か考え、アドバイス、または残忍な修正はありますか?ありがとう!

4

2 に答える 2

4

議論のために、私は少しテストを行いました(以下に表示)-これは、タスクの1つがハングしていて、値を返さないことを示しています。

        Task<int> task1 = Task<int>.Factory.StartNew(() =>
        {
            Thread.Sleep(2000);
            return 10;
        });
        Task<int> task2 = Task<int>.Factory.StartNew(() => 15);
        Task<int>[] tasks = {task1, task2};
        try
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Task.WaitAll(tasks);
            sw.Stop();
            Console.WriteLine(String.Format("tasks completed in {0}ms", sw.ElapsedMilliseconds));
        }
        catch
        {
            Console.WriteLine("Error");
        }
        Console.ReadLine();

これを実行すると、印刷されますtasks completed in 2000ms(数ミリ秒かかるか、数ミリ秒かかります)。私がしたのは、コードをコピーして貼り付け、自分のタスクを追加することだけでした。

だからあなたが"The tasks are [...] not hanging..."それが間違っていると言うところ-彼らはぶら下がっているに違いない。

于 2012-05-19T03:06:38.473 に答える
2

上記のcaesayで説明したように、タスクはハングしている必要があります。これを確認するには、WaitAll呼び出しにデフォルトのタイムアウトを与えることをお勧めします。これを行うには、タスクが終了するまで呼び出しが待機する必要のあるミリ秒数を表すintを渡します。これを試してください

Task.WaitAll(tasks, 10000); //Set to wait for 10 seconds

次に、例外があるかどうか、または「if」ステートメントがヒットしたかどうかを確認します。これが機能する場合は、より長い時間間隔で実験して、タスクで何が起こっているかを確認してください。

また、これら2つのサンプルメソッドに特定の問題があるかどうかを理解するためのテストハーネスとして、タスクなしで(つまり、順次)fooとbar内にあるコードを実行することをお勧めします。

于 2012-05-21T11:37:44.870 に答える