2009-04-21 103 views
2

在c#中的程序中,我有2个线程与主线程分开。 当用户关闭表单时,我想终止主线程中的一个线程。 我该如何去做呢?如果可能,请向我提供代码。从另一个线程操作线程

回答

4

不要使用Thread.Abort作为迄今为止建议其他的答案,除非你希望你的程序处于未知状态(见Ian GriffithsChris Sells更多信息的文章)。如果关闭表单实际上应该是在杀死应用程序,那么你可能是可能是没问题 - 但在这种情况下,我建议只使用后台线程,当所有前台线程终止时它都会自动死机。

从乔·达菲的"Concurrent Programming in Windows"

有些情况下,线程中止始终是安全的两种情况:

  • 线程的主要目的中止是推倒在CLR 的AppDomain卸载线程。 [...]
  • 同步线程异常终止是安全的,只要调用者期望 从该方法抛出异常。 [...]

线程中止的所有其他用途充其量也是有问题的。 [...] 尽管线程中止在理论上比其他线程终止机制更安全,但它们仍然可能发生在不合时宜的时间,导致 不稳定和如果使用时不小心损坏。

(同步线程可放弃是当线程中止本身,而不是由另一个线程被中止。)

对于优美关闭(不冒着进入奇数状态)使用,其被周期性地设置一个标志从表单中检查并从其他线程中检查 - 考虑内存模型(例如,使标志变为挥发性,或者每次测试或设置时都使用锁定)。以我的article on the topic为例。

+0

要关闭表单,我有相应的事件。 我已经命名了我希望作为SecondThread终止的线程。 但是我无法调用SecondThread.Is我在这里失去了一些东西。 此外,如果有任何线程可以中止自己,将简化事情,因为我更喜欢使用标志的概念,因为你已经指出。 – Avik 2009-04-21 05:56:46

1

如果你想杀死你已经开始的线程,我会建议你持有一个对它的引用,如私人领域。当应用程序(或线程)完成时,您可以简单地在该线程上调用Thread.Abort()

例如:

private Thread _myWorker; 

void doSomething() 
{ 
    _myWorker = new Thread(...); 
    _myWorker.Start(); 
} 

void killWorker() 
{ 
    _myWorker.Abort() 
} 

你应该注意到,然后调用Abort()线程上它会提高一个ThreadAbortException,你应该你的员工代码中捕获和处理,以清理等详细信息请参见Thread.Abort

此外,当您的应用程序关闭其主线程(消息循环,又名Application.Run)时,子线程也将被关闭。

+0

子线程只会在后台线程自动关闭。在主线程关闭后,前台线程可以继续运行。 – 2009-04-21 05:31:37

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