2011-08-24 69 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