0

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

大多数示例显示故意调用异常来测试/解释 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

只是为了争论,我做了一个小测试(如下所示) - 它表明您的一项任务正在挂起,并且没有返回值。

        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 来执行此操作,该 int 表示调用必须等待任务结束的毫秒数。试试这个

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

然后看看是否有异常或者你的“if”语句是否被命中。如果这可行,则尝试使用更大的时间间隔来查看任务发生了什么。

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

于 2012-05-21T11:37:44.870 回答