2013-02-19 75 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) 
{} 

这就避免了无限循环的线程在您的标题不会使你的问题更好的开始