2010-02-08 26 views
0

当调用myThread.Start(...)时,我们是否有保证线程已启动? MSDN文档并没有真正具体说明这一点。它表示状态已更改为正在运行。当调用myThread.Start(...)时,我们是否确保该线程已启动?

我在问,因为我看过几次下面的代码。它创建一个线程,启动它,然后循环,直到状态变为运行。是否有必要循环?

Thread t = new Thread(new ParameterizedThreadStart(data)); 
t.Start(data); 
while (t.ThreadState != System.Threading.ThreadState.Running && 
     t.ThreadState != System.Threading.ThreadState.WaitSleepJoin) 
{ 
    Thread.Sleep(10); 
} 

谢谢!

回答

1

如果你在让你的循环继续下去,直到该线程已经“开始”,那么它将取决于究竟你意思设置为“已启动”。这是否意味着该线程已经由操作系统创建并发出信号运行,但不一定是完成了什么?这是否意味着它执行了一个或多个操作?

虽然这很可能没有问题,但是您的循环并非无懈可击,因为理论上可能在您拨打Start和检查ThreadState之间执行整个线程;直接检查属性两次也不是一个好主意。

如果你想坚持检查状态,这样的事情会/可能是更可靠:

ThreadState state = t.ThreadState; 

while(state != ThreadState.Runnung && state != ThreadState.WaitSleepJoin) 
{ 
    Thread.Sleep(10: 

    state = t.ThreadState; 
} 

然而,这仍然是受线程开始的可能性,运行,则停止前你甚至有机会检查。是的,您可以扩大if声明的范围以包含其他状态,但我建议使用WaitHandle来指示线程何时“启动”。

ManualResetEvent signal; 

void foo() 
{ 
    Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod)); 

    signal = new ManualResetEvent(); 

    t.Start(data); 

    signal.WaitOne(); 

    /* code to execute after the thread has "started" */ 
} 

void ThreadMethod(object foo) 
{ 
    signal.Set(); 

    /* do your work */ 
} 

仍然有你检查之前结束线程的方法可行,但你保证有WaitHandle集一旦线程开始。致电WaitOne将无限期阻止,直到Set已被呼叫WaitHandle

+0

谢谢!我喜欢这个想法,并且......这个例子! – Martin 2010-02-08 20:51:12

1

猜猜这取决于你在循环后做什么。如果在它严重依赖线程运行之后发生任何事情,那么检查并不是一个坏主意。 Personnally我会使用一个ManualResetEvent或类似的东西所设定由Thread,而不是检查ThreadStatus

1

Thread.Start导致“被调度执行线程”一个。它将开始,但可能需要一段时间才能在代理中的代码实际运行。事实上,上面的代码也没有做到(我怀疑)作者的意图。将线程的线程状态设置为ThreadState.Running(它发生在Thread.Start)只是确保它已计划运行 - 但是在委托实际执行之前,ThreadState可以是“正在运行”。

由于John Bergess建议,使用ManualResetEvent来通知主线程该线程正在运行比睡眠和检查线程的状态更好的选择。

相关问题