在c#的程序中,我有两个主线程之外的线程。 当用户关闭表单时,我想终止主线程中的一个线程。 我该怎么做呢?如果可能,请提供代码。
答案 0 :(得分:4)
除非您希望自己的程序处于未知状态,否则请不要按照其他答案的建议使用Thread.Abort
(请参阅Ian Griffiths的文章和Chris Sells了解更多信息)。如果关闭表单实际上应该是杀死应用程序,你可能可能好吧 - 但是在这种情况下我建议只使用后台线程,当所有前台线程终止时它将自动死亡。 / p>
来自Joe Duffy的"Concurrent Programming in Windows":
线程中止有两种情况总是安全的:
- 线程中止的主要目的是在CLR期间拆除线程 AppDomain卸载。 [...]
- 如果呼叫者期望,同步线程中止是安全的 从方法抛出的异常。 [...]
线程中止的所有其他用法充其量是有问题的。 [...] 虽然线程中止在理论上比其他线程终止更安全 机制,他们仍然可以在不合适的时间发生,导致 如果不小心使用,就会出现不稳定和腐败。
(同步线程中止是线程自行中止,而不是被另一个线程中止。)
对于正常关闭(没有冒险进入奇数状态)使用从表单定期设置并从其他线程检查的标志 - 考虑内存模型(例如,制作标志每次测试或设置时都会发生变形或使用锁定。有关示例,请参阅我的article on the topic。
答案 1 :(得分:2)
从其他线程中杀死线程几乎总是一个坏主意。正确的方法是通知线程终止,然后等待它。
这是因为线程应该尽可能地对自己的资源负全部责任,包括它们的生命周期。
它不需要复杂,一个简单的变量可以由任何线程设置,并由另一个线程定期读取(这不是真正的任何语言,但你应该知道如果你知道C ):
int exitThread1 = false;
static void Thread1 (void) {
while (!exitThread1) {
// do stuff
}
}
static void mummyProc (void) {
int tid1 = startThread (Thread1);
// dum de dum de dum ...
exitThread1 = true;
joinThread (tid1);
}
答案 2 :(得分:1)
如果你想杀掉你自己开始的线程,我会建议你持有一个引用它,比如私有字段。当应用程序(或线程)结束时,您只需在该线程上调用Thread.Abort()
。
例如:
private Thread _myWorker;
void doSomething()
{
_myWorker = new Thread(...);
_myWorker.Start();
}
void killWorker()
{
_myWorker.Abort()
}
您应该注意,然后在线程上调用Abort()
它将引发一个ThreadAbortException,您应该在工作器代码中捕获并处理清理等。有关详细信息,请参阅Thread.Abort
此外,当您的应用程序关闭其主线程(消息循环,也就是Application.Run)时,子线程也将被关闭。