我打算髮佈一個問題,但提前計算出來,並決定發佈問題和答案 - 或者至少我的意見。使用匿名代理與.NET ThreadPool.QueueUserWorkItem
當使用匿名委託作爲WaitCallback,其中ThreadPool.QueueUserWorkItem在foreach循環中被調用時,似乎將相同的foreach-value傳遞給每個線程。
List<Thing> things = MyDb.GetTheThings();
foreach(Thing t in Things)
{
localLogger.DebugFormat("About to queue thing [{0}].", t.Id);
ThreadPool.QueueUserWorkItem(
delegate()
{
try
{
WorkWithOneThing(t);
}
finally
{
Cleanup();
localLogger.DebugFormat("Thing [{0}] has been queued and run by the delegate.", t.Id);
}
}
}
對於物聯網16事實例的集合,我觀察到,每一個「東西」傳遞給WorkWithOneThing對應到最後一個項目的「東西」名單。
我懷疑這是因爲委託正在訪問't'外部變量。請注意,我也嘗試將Thing作爲參數傳遞給匿名委託,但行爲仍然不正確。
當我重新考慮使用命名的WaitCallback方法並將Thing't'傳遞給該方法的代碼時,viola ...將第i個事件實例正確傳遞到WorkWithOneThing中。
我猜想我在並行的課程。我也想象一下,Parallel.For家族解決這個問題,但是這個庫對於我們來說不是一個選擇。
希望這可以爲他人節省一些時間。
霍華德·霍夫曼
如果試圖編譯這段代碼,你會不會得到一個錯誤「System.Threading.WaitCallback」不走‘0’參數」您指定的任何PARAM – ram 2010-03-12 20:14:01
拉姆 - 嘗試改變上述聲明的: 委託(){ ... } 到 委託 { ... } 這就是我要在做出我的改變之前。希望這可以幫助你。 – 2010-03-22 19:25:07