2009-01-05 56 views
1

我有一個小應用程序,用於在啓動時搜索和存儲大量文件的名稱。我將這個搜索分成幾個Thread對象,每個對象搜索一個目錄,並將結果推回到主線程。c#線程從調試器開始,但不會獨立啓動

當應用程序加載時,我經過每一個線程並加載它:

foreach(Thread t in m_threads) 
{ 
    t.Start(); 
    while(!t.IsAlive){} 
} 

當我在調試器開始這個程序,它的負載和線程快速找到的所有文件。但是,如果我從調試器外部開始凍結。將調試器附加到進程中,我可以看到IsAlive永遠不會返回true。

我是C#線程的新手,所以沒有人有任何想法發生了什麼問題,或者我如何更容易地調試發生了什麼?

回答

2

它可能並不完全相關,爲什麼事情凍結,但你的實現是相當可疑的。您枚舉一組線程,開始每個線程,但是然後阻塞,直到線程完成?我認爲你可能打算做的是啓動所有線程,然後阻塞,直到所有線程都完成。 (注:這是假設你的意思是寫:「而(t.IsAlive){}」,因爲等待線程開始讓更少的意義上)

至於凍結,我們可能需要看代碼的其餘部分。既然你說你是C#線程的新手,看看你上面做了什麼,我認爲你也是線程的新手,這意味着可能有很多地方會出現問題。

1

你也許意思是IsAlive()「永不返回錯誤」。

好吧,如果是這樣,那是因爲你的線程繼續無限地執行。可能是你在這些線程中調用的方法有一個無限循環或其他東西。

3

在您對IsAlive進行檢查之前,線程可能已經完成處理。

爲什麼你在等IsAlive標誌呢?

爲什麼不啓動所有線程,然後在另一個循環中調用Join()來等待線程完成?無需檢查「IsAlive」。

更好的是,爲什麼不使用ThreadPool而不是自己啓動一堆線程呢?

+0

謝謝,我會研究ThreadPools。 – tenpn 2009-01-05 11:08:20

1

它似乎我誤解了我剪切和粘貼創建我的線程代碼的代碼。我假定while(!t.isAlive){}行被阻塞,直到線程能夠正確啓動自己,並認爲這是必要的管理。

我刪除了該行,應用程序啓動罰款的調試器。我稍後在代碼中加入線程,所以應該是這樣。

有沒有「NEWB!」標籤? :)

0

我不知道你在你的線程究竟在做什麼,但我認爲......

多線程+應用程序與調試器不同的行爲附加賽=條件

我很確定你有一些同步問題。

1

隨着你上面提供的代碼,在我看來,你想要順序啓動線程。如果是這樣,你爲什麼需要很多線程? 1個線程可以完成這項工作。

編輯:(你的答案後)

確定。我看到你刪除了有問題的一行。

即使如此,在你的情況下,我會考慮只使用一個線程來加載這些文件名,因爲你只訪問一個IO資源(磁盤)。每個線程都在爭奪這個資源。你有沒有嘗試在窗口中移動1個大文件,然後移動另一個大文件,而第一個文件仍在移動?磁盤的性能下降。因此,我只會爲每個不同的IO資源創建一個線程。

1

我會建議不要保留線程的集合,而是使用Threadstarts來代替。 如果稍後加入它們,則無需等待線程運行,因此不需要while循環。 確保您的線程標記爲後臺線程,以便在執行後自動清理它們。

我會這樣做: List threadStarters = new List();

foreach (ThreadStart ts in threadStarters) 
{ 
    Thread t = new Thread(ts); 
    t.IsBackground = true; 
    t.Start(); 
}