簡體   English   中英

System.Threading.Tasks in for循環問題

[英]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()); }})));
}

閱讀更多:

foreach標識符和閉包

http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx

object36963566必須是切片列表中的最后一個實例

這是因為foreach如何在當前的.Net實現中工作。 雖然將來會修復。

您需要閱讀關閉循環變量的結果,該變量被認為對於理解foreach在這種情況下如何工作有害

Task.CurrentId +"Info object"+ info.GetHashCode()

info在上面的代碼參照項目列表中的tiles 您正在創建的delegate將不會使用在創建它(委托)時引用的項目info 相反,它將使用info的當前值(信息在方法/委托實際運行時指向的值),這顯然指向列表的最后一項。 這就是你得到這種行為的原因

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM