[英]System.Threading.Tasks in a for loop issue
由於以下問題,我正在撕掉我的頭發。 我有一些代碼循環遍歷對象列表並為每個對象創建一個處理任務。
IList<TileInfo> tiles = tileSource.Schema.GetTilesInView(extent, level);
List<Task> renderingTasks = new List<Task>();
foreach (TileInfo info in tiles) {
renderingTasks.Add(Task.Factory.StartNew(new Action(delegate {
Console.WriteLine(Task.CurrentId +"Info object"+ info.GetHashCode());
}
})));
}
此代碼打印:
1Info object36963566
2Info object36963566
3Info object36963566
4Info object36963566
5Info object36963566
6Info object36963566
7Info object36963566
8Info object36963566
9Info object36963566
10Info object36963566
11Info object36963566
12Info object36963566
...
正如您所看到的,問題是任務似乎都引用了一個對象!
為什么這些任務都只使用列表中的一個對象?
謝謝你的幫助
我會嘗試在一瞬間添加更多細節,但這是關閉變量。 將您的代碼更改為:
基本上你需要做的是在循環中創建一個新變量,等於循環內部工作之外的單個聲明。
IList<TileInfo> tiles = tileSource.Schema.GetTilesInView(extent, level);
List<Task> renderingTasks = new List<Task>();
foreach (TileInfo info in tiles)
{
TileInfo closingInfo = info;
renderingTasks.Add(Task.Factory.StartNew(new Action(delegate {
Console.WriteLine(Task.CurrentId +"Info object"+ closingInfo.GetHashCode()); }})));
}
閱讀更多:
object36963566
必須是切片列表中的最后一個實例
這是因為foreach
如何在當前的.Net實現中工作。 雖然將來會修復。
您需要閱讀關閉循環變量的結果,該變量被認為對於理解foreach在這種情況下如何工作有害 。
Task.CurrentId +"Info object"+ info.GetHashCode()
info
在上面的代碼參照項目列表中的tiles
。 您正在創建的delegate
將不會使用在創建它(委托)時引用的項目info
。 相反,它將使用info
的當前值(信息在方法/委托實際運行時指向的值),這顯然指向列表的最后一項。 這就是你得到這種行為的原因
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.