Task.WaitAll Index Out of Bounds Exception Cause

时间:2014-08-16 18:33:16

标签: c# task aggregateexception

为什么这不完整?相反,它抛出一个异常,就像异常没有被捕获一样。此外,例外"索引超出数组范围"对我没有意义。

        int n = 3;
        string[] names = new string[] { "sally", "fred", "gina" };
        Task[] myTasks = new Task[n];
        for (int y = 0; y < n; y++)
        {
            myTasks[y] = Task.Factory.StartNew(() =>
            {
                Action<string> action = (name) =>
                {
                    try
                    {
                        throw new Exception(name + ", I bet you can't catch me.");
                    }
                    catch (Exception e)
                    {
                        //I caught you... didn't I?
                    }
                };
                action(names[y]);
            });
        }

        Task.WaitAll(myTasks);
        Console.WriteLine("All tasks complete.");//This line is never reached;

2 个答案:

答案 0 :(得分:7)

你在StartNew括号内的lambda函数正在形成一个闭包,即&#34;捕获&#34;外部变量&#34; y&#34; ...它在循环迭代期间没有访问它的值......而是在访问捕获的变量时lambda函数......当它试图获取值时。

你的&#34; y&#34;变量最终达到了值#34; 3&#34; (通过循环y++)....因为这导致&#34;循环创建你的&#34;动作&#34;)....退出(即3不小于3)。

但是当您创建的任何Task正在执行第action(names[y])行时,它正在访问已关闭的变量&#34; y&#34; ...& #34;可以&#34;已经达到&#34; 3&#34; ...以及&#34; 3&#34;在你的数组中不是一个有效的索引....这一切都取决于这些任务的计划速度或速度,无论你是否遇到问题......一个典型的竞争条件。

答案 1 :(得分:0)

我确实通过在名称

的任务之外设置变量来确定
var name = names[y];

并使用它而不是从任务中访问数组,它的工作原理。我仍然不明白为什么。