2011-08-24 127 views
-2

我有主線程(MainThread),我在其上創建新的Thred(讓我們稱它爲NewThread)。在NewThread中,我調用了一個想要爲MainThread調用某個方法的方法。C#線程問題

問題是,當我從MainThread調用NewThread.Join()時,NewThread的Invoke方法無法完成/終止(並且整個應用程序永遠凍結...),因爲MainThread正在等待NewThread終止...

......就像惡性循環......任何想法如何解決它?我需要有可能從MainThread終止/中止NewThread,並確保NewThread不再存在。

我希望我足夠具體。

主線程:

void method() 
    { 
     if(currentthread!=null) 
     { 
      currentthread.Join(); 
      currentthread=null; 
     } 

     sth... 

     Backgroundworker worker = new Backgroundworker(); 
     worker.DoWork += delegate (...) 
      { 
       currentthread=Thread.CurrentThread; 
       Func(); 
      } 
      .... 
} 

NewThread:

delegate void FuncDel(); 
void Func() 
{ 

    if(MainThread.InvokeRequired) 
{ 
    FuncDel funcD = new FuncDel(); 
    MainThread.InvokeRequired(funcD); 
      return; 
} 
.... 
} 
+1

我們需要看你的代碼。 – Woot4Moo

+1

你會發布你的代碼嗎? – ChrisNel52

+0

你用什麼技術在MainThread上調用你的方法?是某種Control.Invoke或類似的? – michalczerwinski

回答

2

那麼,顯而易見的答案是你的主線程應該永遠不會加入()你的工作線程,如果有機會的工作線程是怎麼回事嘗試在主線程上調用()一些東西。

如果您只使用Join()等待主線程關閉,則應首先執行類似於Thread.Abort()的操作,或者更好地使用線程同步對象,如互斥鎖或共享變量,向工作線程表明它需要中止。一旦你有信號通知工作線程中止,然後允許你的主線程加入()它;您的工作線程應該總是在嘗試調用主線程上的方法之前檢查它是否已中止。

如果由於某些其他原因而使用Join(),則應該再次查看線程同步對象,如Mutex。這些允許你的線程等待對方發送信號 - 你的工作線程可以在你需要調用()之前喚醒你的主線程,以確保你的主線程獲得CPU時間來完成它的工作。

+0

+1:雖然我傾向於在'Mutex'上使用'EventWaitHandle'。 –

0

這就是Thread.Join所做的,它會阻止您的調用線程,直到連接線程終止。我想我不知道你爲什麼使用連接,如果你只是想在另一個線程上調用。如前所述,代碼將有助於澄清情況。

如果你的實現不允許你阻塞你的主線程,你可以通過輪詢ThreadState來檢查線程的狀態與使用Join的狀態。

0

這聽起來像你幾乎想要取消模式。試試這個TPL選項:

CancellationTokenSource cts = new CancellationTokenSource(); 
Task.Factory.StartNew(() => 
    { 
     if(cts.Token.IsCancellationRequested) 
      return; 

     // Do Stuff 
    }); 

基本上可以激發關閉你想做的操作的任務,如果你需要取消它,你可以簡單地調用

cts.Cancel(); 

你舉的例子是相當令人費解的;有一個線程剝離來調用某些方法與原始線程無關。

+0

不幸的是,TPL與.net 4一起工作。0 - 雖然我使用以前的版本。 – santBart