调用myThread.Start(...)时,我们是否确保线程已启动?

时间:2010-02-08 20:17:43

标签: multithreading c#-3.0

调用myThread.Start(...)时,我们是否确保线程已启动? MSDN文档并没有真正具体。它说状态改为Running。

我问,因为我已经看过几次以下代码。它创建一个线程,启动它然后循环,直到状态变为Running。这有必要循环吗?

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);
}

谢谢!

3 个答案:

答案 0 :(得分:1)

猜猜这取决于循环后你在做什么。如果在它严重依赖于线程运行之后发生任何事情,那么检查并不是一个坏主意。我个人使用ManualResetEventThread设置的类似内容,而非检查ThreadStatus

答案 1 :(得分:1)

没有。 Thread.Start导致“线程被安排执行”。它将启动,但在您的委托中的代码实际运行之前可能需要一段(短)时间。事实上,上面的代码也没有做(我怀疑)作者的意图。将线程的threadstate设置为ThreadState.Running(确实发生在Thread.Start中)只是确保它被安排运行 - 但是在委托实际执行之前ThreadState可以是“Running”。

正如John Bergess建议的那样,使用ManualResetEvent通知主线程线程正在运行是一个比睡眠和检查线程状态更好的选择。

答案 2 :(得分: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为止。