线程不会在应用程序关闭时中止
我有一个应用程序在单独的Thread
中执行一些后台任务(网络侦听&读取)。但是,当我关闭应用程序时(单击标题栏上的“x”按钮),线程似乎没有被终止/中止。 是因为主线程程序是while(true) {...}
? 这里有什么解决方案?我正在寻找线程的“中断”标志作为“while”循环的条件,但没有找到任何标志。线程不会在应用程序关闭时中止
最简单的方法是将线程的IsBackground属性设置为true。这将阻止它保持应用程序的开放。当所有非后台线程终止时,应用程序终止。
停止线程的更可控制的方法是发送一条消息,使其干净地关闭并确保它在终止主线程之前终止。
我不推荐的方法是致电Thread.Abort
。这有一些问题,其中之一是它不能保证终止线程。从文档:
调用此方法通常终止线程。
强调我的。
好,而不是while(true)
,也许你应该:
while(appIsRunning)
{
}
而且,在你的形式结束活动,
appIsRunning = false;
thread.Join(2000);
在最后一行是只是为了确保您等待线程干净地完成。还有很多其他的方法可以强制结束一个线程,但问题就在那里:你不希望成为,你希望它们尽可能自然地发生。
加入后,您可以检查线程的状态以查看它是否已完成。如果不是,然后(并且只有这样)才会强制终止并且可能会通知您的用户(或写入日志记录)某些事情没有按照应有的方式结束。
是的,但请记住使用'volatile'或'lock'或其他一些同步方法。 – 2010-05-17 21:57:05
@Mark:这里可能是完全错误的,但是由于子线程只读取并且主线程只写入,是否有机会出现错误? – 2010-05-17 22:42:16
如果不同步,则不保证在另一个线程中可以看到一个线程的appIsRunning更改。你可以在这里阅读更多:http://timl.net/2009/03/volatile-memory.html – 2010-05-17 22:46:54
你可以提高从标识符名称,而(真)环路
void DoWork() {
while(!ShouldIQuitManualResetEvent.WaitOne(0)) {
// do something
}
IDidQuitManualResetEvent.Set()
}
更优雅一点,短。
您可以随时生效的问题:
class Program
{
public static void Main()
{
// ... do stuff
Environment.Exit(Environment.ExitCode);
}
}
更好的方法是马克已经提到的Thread.IsBackground属性设置为true。
您就可以开始您的主题:
ThreadPool.QueueUserWorkItem(DoStuff, input)
而且它会随着应用程序关闭自动中止。
+1消息方法。'while(stayAlive)'而不是'true'会更干净,即使循环可能需要几秒钟时间才能清除。 – user7116 2010-05-17 21:58:43