Threading.Tasks:WaitAll()的概念

时间:2012-05-19 02:21:13

标签: c# .net multithreading task-parallel-library task

我在控制台应用程序中遇到一个奇怪的问题(不确定这是否与它有关)并使用了任务。

大多数示例显示故意调用Exception来测试/解释WaitAll的概念 - 但在我的情况下,似乎我正在做一些根本上错误的(或者不完全理解)。< / p>

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还在等待 - 或许它正在等待,这就是我缺少的东西(等待的是什么)?

任何想法,建议或残酷的更正?谢谢!

2 个答案:

答案 0 :(得分:4)

仅仅为了争论我做了一点测试(如下所示) - 它表明你的一个任务是挂起,而不是返回一个值。

        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..."是假的 - 他们必须挂起。

答案 1 :(得分:2)

正如上面的caesay所解释的那样,任务必须悬而未决。要检查这一点,我建议您给WaitAll呼叫一个默认时间。你可以通过传入一个int来做到这一点,这个int表示调用必须等待任务结束的毫秒数。试试这个

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

然后查看是否有异常或是否命中了“if”语句。如果这样做,那么试验更大的时间间隔,看看任务发生了什么。

另外,我建议运行foo和bar中的代码,不要将任务(即顺序)作为测试工具,以了解这两种示例方法是否存在任何特殊问题。