2015-01-12 4 views
0

У меня есть 2 вопроса о Task factory in C#. 1) Почему результат в этом коде случайно изменяется? Обратите внимание, что если я пройду через код, это сработает. 2) Если я изменяю метод Div для исключения исключений, то метод WaitForAll взрывается. Есть ли обходной путь для этого?task library производит случайные результаты

List<Task<float>> tasks = new List<Task<float>>(); 
for (float i = -3.0f; i < 3.0f; i+=1.0f) 
{ 
    Console.WriteLine("sent " + i); 
    Task<float> task = Task.Factory.StartNew<float>(() => Div(5.0f, i)); 
    tasks.Add(task); 
} 
Task.WaitAll(tasks.ToArray()); 
foreach(Task<float> t in tasks) 
{ 
    if (t.IsFaulted) 
    { 
     Console.WriteLine("Something went wrong: " + t.Exception); 
     break; // abort 
    } 
    else 
    { 
     Console.WriteLine("result: " + t.Result); 
    } 
} 

private static float Div(float a, float b) 
{ 
    Console.WriteLine("got " + b); 
    if (b == 0) return 0.0f;// throw new Exception("Divide by zero"); 
    return a/b; 
} 

результат случайным образом изменяется. Вот один из результатов:

sent -3 
sent -2 
sent -1 
sent 0 
sent 1 
sent 2 
got 2 
got 2 
got 2 
got 2 
got 2 
got 3 
result: 2.5 
result: 1.666667 
result: 2.5 
result: 2.5 
result: 2.5 
result: 2.5 

ответ

2

Закрытие.

Присвоить i в локальные переменный в пределах for цикла, прежде чем передать его в Task:

List<Task<float>> tasks = new List<Task<float>>(); 
for (float i = -3.0f; i < 3.0f; i+= 1.0f) 
{ 
    float input = i; 
    Console.WriteLine("sent " + i); 
    Task<float> task = Task.Factory.StartNew<float>(() => Div(5.0f, input)); 
    tasks.Add(task); 
} 

В противном случае i будет распределен между петлей и всеми задачами, поэтому, когда приращение цикла его с помощью i += 1.0f все в задачи также видят изменения. Вот почему вы получаете кучу 2 s распечатайте как got.

Смежные вопросы