【发布时间】:2010-08-26 12:50:09
【问题描述】:
我有一个本地线程,它在主线程的按钮单击事件上启动。它的名字是RegistrationThread。我想在另一个停止按钮单击事件上停止这个线程。
如何停止 RegistrationThread 这是一个本地线程并且我无法通过其名称访问该线程?
如果我收到RegistrationThread,是否可以暂停它?如何做到这一点?
【问题讨论】:
标签: c# multithreading
我有一个本地线程,它在主线程的按钮单击事件上启动。它的名字是RegistrationThread。我想在另一个停止按钮单击事件上停止这个线程。
如何停止 RegistrationThread 这是一个本地线程并且我无法通过其名称访问该线程?
如果我收到RegistrationThread,是否可以暂停它?如何做到这一点?
【问题讨论】:
标签: c# multithreading
中止线程通常是最后的手段。原因是它会导致很多意想不到的副作用。最佳实践是允许工作线程在预定的安全点优雅地结束。这可以通过许多不同的方式正确完成。最简单的方法之一是设置一个标志,指示工作线程应该开始关闭。
public class YourForm : Form
{
private volatile bool m_Stop = false;
private void StartButton_Click(object sender, EventArgs e)
{
var thread = new Thread(
() =>
{
while (...)
{
// Periodically poll the m_Stop flag.
if (m_Stop)
{
break;
}
}
});
thread.Start();
}
private void StopButton_Click(object sender, EventArgs e)
{
m_Stop = true;
}
}
如果您真的想要中止线程,那么您可以随时保存对Thread 的引用,然后从停止按钮单击事件中调用Abort。
【讨论】:
据我所知,没有很好的方法可以通过名称查找线程,并且 Thread.Name 基本上只是为了使调试更容易而缩进。为什么不只保留对线程对象的引用呢?
在 .net 中可以同时停止(中止)和挂起另一个线程,但两者都不是特别可取的事情。
调用 Thread.Abort 通常被认为是不好的形式。通知在另一个线程中运行的代码该中止并让它在安全点自行退出会更安全。考虑到 MSDN 文档仅声称在“通常”线程上调用 Abort() 会中止线程。这应该表明 API 真的不适合在结果很重要时使用。
挂起一个线程至少和中止它一样邪恶——如果它持有锁,挂起它可能会导致死锁。即使您的代码不包含显式锁,.net 运行时也有许多幕后(例如用于类初始化)可能会给您带来麻烦。结果,微软几年前就弃用了 Thread.Suspend。
您为什么不向我们提供更多关于您在更高级别上尝试做什么的信息,也许我们可以帮助您找到更好的方法。
【讨论】: