在下面的問題中,我發現了一種以類型安全的方式調用QueueUserWorkItem的巧妙方法,在該方法中傳遞委託而不是WaitCallBack和對象。然而,它不會按照人們所期望的方式工作。帶委託的QueueUserWorkItem不起作用,但WaitCallBack不起作用
下面是一些示例代碼和輸出演示問題。
for (int i = 0; i < 10; ++i)
{
// doesn't work - somehow DoWork is invoked with i=10 each time!!!
ThreadPool.QueueUserWorkItem(delegate { DoWork("closure", i); });
// not type safe, but it works
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), Tuple.Create(" WCB", i));
}
void DoWork(string s, int i)
{
Console.WriteLine("{0} - i:{1}", s, i);
}
void DoWork(object state)
{
var t = (Tuple<string, int>)state;
DoWork(t.Item1, t.Item2);
}
這裏是輸出:
closure - i:10
WCB - i:0
closure - i:10
WCB - i:2
WCB - i:3
closure - i:10
WCB - i:4
closure - i:10
WCB - i:5
closure - i:10
WCB - i:6
closure - i:10
WCB - i:7
closure - i:10
WCB - i:8
closure - i:10
WCB - i:9
WCB - i:1
closure - i:10
注意,使用封閉打電話QueueUserWorkitem時,I = 10調用過,但使用WaitCallBack當你得到正確的價值觀,0- 9。
所以我的問題是:
- 爲什麼用做它的關閉/委託方式時,是不是我的正確值傳遞?
- 我到底是怎樣變成10的?在循環中,它只有0-9的值是正確的?
循環變量捕獲,再次。該術語的搜索堆棧溢出。 – usr
@usr或者,您可以找到其中一個重複項並投票結束。這將是更有效的事情。 – casperOne