2013-02-19 43 views
-1

我正在創建一個應用程序,需要在新線程中完成一些工作並將結果保存到靜態列表中,然後線程自然死亡。這個附加線程只能有一個實例在執行,所以當負責創建線程查找線程的函數已經工作時,它應該返回。無限循環等待線程變爲活動{while!thread.isAlive; }

當創建我的appliaction我使用MSDN上該指南:http://msdn.microsoft.com/en-us/library/7a2f3ay4%28v=vs.80%29.aspx

本指南說:

if (TibiaControl.PathFinder.PathFinderThread != null && TibiaControl.PathFinder.PathFinderThread.IsAlive) 
    return false; 

TibiaControl.PathFinder Finder = new TibiaControl.PathFinder(targetX, targetY); 
TibiaControl.PathFinder.PathFinderThread = new Thread(new ThreadStart(Finder.FindPath)); 
TibiaControl.PathFinder.PathFinderThread.Start(); 
SystemControl.DebugMessage(0, "_findPath -- 1"); 
while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ; 
Thread.Sleep(1); 
SystemControl.DebugMessage(0, "_findPath -- 2"); 

但當:

// Create the thread object. This does not start the thread. 
Worker workerObject = new Worker(); 
Thread workerThread = new Thread(workerObject.DoWork); 

// Start the worker thread. 
workerThread.Start(); 
Console.WriteLine("main thread: Starting worker thread..."); 

// Loop until worker thread activates. 
while (!workerThread.IsAlive); 

// Put the main thread to sleep for 1 millisecond to 
// allow the worker thread to do some work: 
Thread.Sleep(1); 

所以我在我的應用程序中使用此代碼高頻執行此功能(如每20-30ms一次),它發生我的應用程序卡住

線和主線程卡在無限循環(好像線程已經擁有了它是一個while循環發生之前所做的工作)。我該如何解決這個問題?

+2

編寫代碼後立即停止的情況。請閱讀[faq]和[ask] – 2013-02-19 15:43:36

+1

爲什麼要讓主循環暫停,直到工作線程啓動? – mbeckish 2013-02-19 15:49:47

+3

如果您只是要阻止主線程,直到工作線程完成使用工作線程獲得的內容爲止?爲什麼不在當前線程中完成這項工作? – Servy 2013-02-19 15:50:32

回答

2

我想你可能盲目地複製了,你不需要例如一些代碼:

while (!TibiaControl.PathFinder.PathFinderThread.IsAlive) ; 
Thread.Sleep(1); 

他們這樣做的原因是爲了證明他們的RequestStop方法的有用性。

+0

問題是我正在等待線程啓動。添加一個易變的布爾而不是thread.IsAlive,並刪除while循環修復(如現在的測試)問題。 – user1792042 2013-02-19 16:08:22

1

我不會將該代碼用作任何有用應用程序的源代碼。首先,線程有更好的方法等待。例如,ManualResetEventSlim。其次,很難從你發佈的代碼中知道IsAlive是否爲volatile。即使如此,在一個x86系統中,真的不會做任何事情。特殊代碼。我會建議使用更安全,更明確的線程安全值讀取形式。例如:

while (0 == Interlocked.Read(ref workerThread.IsAlive)); 

這意味着 改變 創建一個新的變量的IsAlive 爲長。但是,在一個單一的CPU系統中,你只讓一個CPU很忙,而其他線程很少有機會使用它。你應該控制讓給其他線程:

while (0 == Interlocked.Read(ref workerThread.IsAlive)) Thread.Sleep(1); 

但是,我認爲首先是示例代碼是一個壞主意。揣摩什麼需要做的細節...

欲瞭解更多信息,請參閱http://msdn.microsoft.com/en-us/magazine/jj863136.aspxhttp://msdn.microsoft.com/en-us/magazine/jj883956.aspx

+0

問題是我正在等待線程啓動。添加一個易變的布爾而不是thread.IsAlive,並刪除while循環修復(如現在的測試)問題。 – user1792042 2013-02-19 16:07:53

0

合併的IsAlive循環與查詢的ThreadState:

while (!myThread.IsAlive 
    && myThread.ThreadState != ThreadState.Stopped 
    && myThread.ThreadState != ThreadState.Aborted) 
{} 

這就避免了無限循環的線程在您的標題不會使你的問題更好的開始