线程不会在应用程序关闭时中止

问题描述:

我有一个应用程序在单独的Thread中执行一些后台任务(网络侦听&读取)。但是,当我关闭应用程序时(单击标题栏上的“x”按钮),线程似乎没有被终止/中止。 是因为主线程程序是while(true) {...}? 这里有什么解决方案?我正在寻找线程的“中断”标志作为“while”循环的条件,但没有找到任何标志。线程不会在应用程序关闭时中止

最简单的方法是将线程的IsBackground属性设置为true。这将阻止它保持应用程序的开放。当所有非后台线程终止时,应用程序终止。

停止线程的更可控制的方法是发送一条消息,使其干净地关闭并确保它在终止主线程之前终止。

我不推荐的方法是致电Thread.Abort。这有一些问题,其中之一是它不能保证终止线程。从文档:

调用此方法通常终止线程。

强调我的。

+1

+1消息方法。'while(stayAlive)'而不是'true'会更干净,即使循环可能需要几秒钟时间才能清除。 – user7116 2010-05-17 21:58:43

好,而不是while(true),也许你应该:

while(appIsRunning) 
{ 
} 

而且,在你的形式结束活动,

appIsRunning = false; 
thread.Join(2000); 

在最后一行是只是为了确保您等待线程干净地完成。还有很多其他的方法可以强制结束一个线程,但问题就在那里:你不希望成为,你希望它们尽可能自然地发生。

加入后,您可以检查线程的状态以查看它是否已完成。如果不是,然后(并且只有这样)才会强制终止并且可能会通知您的用户(或写入日志记录)某些事情没有按照应有的方式结束。

+0

是的,但请记住使用'volatile'或'lock'或其他一些同步方法。 – 2010-05-17 21:57:05

+0

@Mark:这里可能是完全错误的,但是由于子线程只读取并且主线程只写入,是否有机会出现错误? – 2010-05-17 22:42:16

+1

如果不同步,则不保证在另一个线程中可以看到一个线程的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) 

而且它会随着应用程序关闭自动中止。