類似的問題被問到here,但答案一般都與lambda表示法有關。我得到沒有拉姆達類似的結果,所以我認爲我會問一些澄清:線程啓動的競態條件
說我有這樣的事情:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
人們期望的輸出如下:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
現在我意識到線程並不是以任何特定的順序開始的,所以我們假設上面的行可以以任何順序出現。
但這不是發生了什麼。 什麼,而不是發生:
Thread 3
Thread 4
Thread 4
Thread 4
Thread 4
或類似的東西,這使我相信,而不是傳遞價值,如果我,它是通過基準。 (這很奇怪,因爲int是一個值類型)。
做這樣的事情:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
int j = i;
Console.WriteLine("Thread " + j);
}))).Start();
並沒有幫助,雖然我們已經取得了我的副本。我假設原因是它沒有及時提供我的副本。
做這樣的事情:
for (int i = 0; i < 5; i++)
{
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
Thread.Sleep(50);
}
似乎解決這個問題,但它是非常不可取的,因爲我們在每次迭代50ms的浪費,更何況一個事實,即如果計算機負載過重然後也許50ms可能是不夠的。
這裏是我當前的特定問題的例子:
Thread t = new Thread(new ThreadStart(delgate()
{
threadLogic(param1, param2, param3, param4);
}));
t.Start();
param1 = param2 = param3 = param4 = null;
有:
void threadLogic(object param1, object param2, object param3, object param4)
{
// Do some stuff here...
}
我想threadLogic()在它自己的線程中運行,但上面的代碼給出了一個空參考例外。我認爲這是因爲在線程有機會開始之前將值設置爲null。
再次,把Thread.Sleep(100)的作品,但它是從各個方面的可怕的解決方案。 你們對這種特殊類型的比賽狀況有何建議?
見http://stackoverflow.com/questions/1930133/c-closures-why-is-the-loopvariable-captured-by-reference和http://stackoverflow.com/問題/ 1923577 /不同行爲時,什麼時候開始線程參數化線程啓動vs匿名/ – nos 2011-02-08 23:31:41