2014-09-29 22 views
0

每次調用Process方法時,payload.DaysRemaining值都會重置爲零。使用任務維護for循環內的狀態

我明白,包含要執行的任務的方法將獨立於其中聲明的任務對象執行,這會導致在包含方法中聲明的變量鬆動狀態。

那麼如何使用依賴於方法範圍變量的任務來維護for循環中的狀態?

private static async Task Assign(Payload payload) 
{ 
    var duration = payload.DaysRemainingToJobsDue.First().Key; 
    var tasks = new List<Task>(); 

    for (var daysRemaining = duration; daysRemaining >= 0; daysRemaining--) 
    { 
     payload.DaysRemaining = daysRemaining; 

     var task = new Task(() => 
     { 
      Process(payload); 
     }); 

     tasks.Add(task); 
     task.Start(); 
    } 

    Task.WaitAll(tasks.ToArray()); 
    return; 
} 

private static void Process(object state) 
{ 
    var payload = state as Payload; 

    foreach (var job in payload.Jobs) 
    { 
     var compareResult = job.DueDate.CompareTo(DateTime.Now.AddDays(payload.DaysRemaining)); 

     var withinRange = compareResult <= 0; 

     if (withinRange) 
     { 
      HashSet<Job> existingJobsDue = null; 
      var pendingJobsExist = payload.DaysRemainingToJobsDue.TryGetValue(payload.DaysRemaining, out existingJobsDue); 

      if (pendingJobsExist) 
      { 
       existingJobsDue.Add(job); 
      } 
      else 
      { 
       existingJobsDue = new HashSet<Job>(); 
       existingJobsDue.Add(job); 
      } 

      payload.DaysRemainingToJobsDue[payload.DaysRemaining] = existingJobsDue; 
     } 
    } 
} 

回答

0

該效果被稱爲closure

你需要做的就是創建lambda表達式中的變量的本地副本什麼被傳遞到新創建的Task

var task = new Task(() => 
{ 
    var localPayload = payload; 
    Process(localPayload); 
}); 
+0

-1:你在正確的軌道上,但是這僅執行會如果'Payload'類型是'struct',則工作。我不相信提供足夠的信息來作出這樣的假設。 – 2014-10-13 10:21:19

+0

@Sam這與結構無關。你爲什麼那麼想? – 2014-10-13 10:59:06

+0

@Sam引用類型關閉有類似的效果:http://lostechies.com/derickbailey/2009/02/23/closures-in-c-variable-scoping-and-value-types-vs-reference-types/ – 2014-10-13 11:36:29