請檢查下面的代碼示例:意外行爲ThreadPool.QueueUserWorkItem
public class Sample
{
public int counter { get; set; }
public string ID;
public void RunCount()
{
for (int i = 0; i < counter; i++)
{
Thread.Sleep(1000);
Console.WriteLine(this.ID + " : " + i.ToString());
}
}
}
class Test
{
static void Main()
{
Sample[] arrSample = new Sample[4];
for (int i = 0; i < arrSample.Length; i++)
{
arrSample[i] = new Sample();
arrSample[i].ID = "Sample-" + i.ToString();
arrSample[i].counter = 10;
}
foreach (Sample s in arrSample)
{
ThreadPool.QueueUserWorkItem(callback => s.RunCount());
}
Console.ReadKey();
}
}
此示例的預期輸出應該是這樣的:
Sample-0 : 0
Sample-1 : 0
Sample-2 : 0
Sample-3 : 0
Sample-0 : 1
Sample-1 : 1
Sample-2 : 1
Sample-3 : 1
.
.
.
但是,當您運行此代碼,它會顯示這樣的代替:
Sample-3 : 0
Sample-3 : 0
Sample-3 : 0
Sample-3 : 1
Sample-3 : 1
Sample-3 : 0
Sample-3 : 2
Sample-3 : 2
Sample-3 : 1
Sample-3 : 1
.
.
.
我可以理解,廣告執行可能會有所不同,因此計數不會以循環方式增加。然而,我不明白,爲什麼所有的ID
都顯示爲Sample-3
,而執行顯然是彼此獨立的。
Arent不同的對象被用於不同的線程?
另一天,另一個人不知道如何正確使用倒閉。難怪Java是如此不願意添加它們...... – leppie 2011-01-20 07:54:42
leppie說的是你捕獲變量`s`而不是它的值。線程執行時,迭代完成,`s`保留最後一個值。 – Zarat 2011-01-20 07:59:13