循环运行任务抛出ArgumentOutOfRangeException

时间:2014-04-16 15:03:24

标签: c# for-loop task

我想包装Task类,但是当我运行我的代码时,它会抛出ArgumentOutOfRangeException。这很奇怪,因为当我使用调试器时,没有抛出任何异常。 这是我的代码的“工作”示例。

public class TaskService
{
private Task<int>[] _tasks;
private List<DateTime> _arguments = new List<DateTime>();

public void AddArgument(DateTime argument)
{
    _arguments.Add(argument);
}

public void RunTask(Func<DateTime, int> doWork)
{
    _tasks = new Task<int>[_arguments.Count];

    for (int i = 0; i < _arguments.Count; i++)
    {
        _tasks[i] = Task.Factory.StartNew<int>(() => doWork(_arguments[i])); // Exception is throwing here: _arguments[i]
        // by some reason i = 2, but _arguments.Count = 2 so it should never happed
    }
}

public void Wait()
{
    Task.WaitAll(_tasks);
}
}

class Program
{
static void Main(string[] args)
{
    TaskService taskService = new TaskService();

    taskService.AddArgument(new DateTime(2014, 1, 1));
    taskService.AddArgument(new DateTime(2014, 2, 1));
    taskService.RunTask(DoWork);
    taskService.Wait();
}

public static int DoWork(DateTime day)
{
    Console.WriteLine(day);
    return 0;
}
}

1 个答案:

答案 0 :(得分:3)

由于关闭(further reading),您的问题就出现了。 i变量在lambda中捕获。完成创建任务后(循环后)i的值为2。当任务开始时,他们仍然指的是这个特定的int实例。试试这个:

public void RunTask(Func<DateTime, int> doWork)
{
    _tasks = new Task<int>[_arguments.Count];

    for (int i = 0; i < _arguments.Count; i++)
    {
        var index = i;
        _tasks[i] = Task.Factory.StartNew<int>(() => doWork(_arguments[index]));
    }
}