关闭multithreading应用程序

我正在尝试为我的C#应用​​程序编写一个ThreadManager。 我创建了几个线程:
我文本作者的一个主题。
一个监视某些统计信息的线程。
multithreading执行大量计算(每个核心最多4个线程,我在2x四核服务器上运行我的应用程序)。

我的应用程序通常一次最多运行24小时,因此所有线程都在开始时创建,并且它们会在应用程序运行的整个过程中持续存在。

我希望有一个单独的位置,我“注册”我的所有踏板,当应用程序关闭时,我只需调用一个方法,它会遍历所有已注册的线程并关闭它们。

为此我设计了以下课程:

public class ThreadManager { private static Object _sync = new Object(); private static ThreadManager _instance = null; private static List _threads; private ThreadManager() { _threads = new List(); } public static ThreadManager Instance { get { lock (_sync) { if (_instance == null) { _instance = new ThreadManager(); } } return _instance; } } public void AddThread(Thread t) { lock (_sync) { _threads.Add(t); } } public void Shutdown() { lock (_sync) { foreach (Thread t in _threads) { t.Abort(); // does this also abort threads that are currently blocking? } } } } 

我想确保我的所有线程都被杀死,因此应用程序可以正常关闭,并且在一些计算过程中关闭也很好。 我应该知道这里有什么吗? 鉴于我的情况,这种做法是否合适?

如果将线程设置为后台线程,则在关闭应用程序时将终止它们。

 myThread.IsBackground = true; 

显然,如果您需要在关机前完成线程,这不是您想要的解决方案。

当所有其他方法都失败时 ,您就会执行中止线程。 这是一件危险的事情,你应该只做最后的手段。 执行此操作的正确方法是创建线程逻辑,以便每个工作线程在主线程为其提供关闭自身的命令时快速正确地响应。

巧合的是,这是我本周博客的主题。

http://blogs.msdn.com/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx

如果在关机运行时调用AddThread怎么办?

当关闭完成时,在AddThread中等待的线程将向集合中添加一个新线程。 这可能会导致您的应用挂起。

添加您只在Shutdown中设置的bool标志以防止这种情况发生。

 bool shouldGoAway = false; public void AddThread(Thread t) { lock (_sync) { if( ! shouldGoAway ) _threads.Add(t); } } public void Shutdown() { lock (_sync) { shouldGoAway = true; foreach (Thread t in _threads) { t.Abort(); // does this also abort threads that are currently blocking? } } 

此外,您不应该使用静态成员 – 因为您拥有Singleton实例,所以没有理由这样做。

.Abort()不会中止在非托管空间中阻塞的线程。 所以,如果你这样做,你需要使用其他一些机制。

我所知道的唯一具体问题是: http : //www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx

但我不得不求助于这样的设计。 您可以强制每个线程定期检查一些标志是否需要关闭,关闭时,设置该标志并等待所有线程完成(使用Join())。 这种感觉有点像受控关机。

如果您不关心工作线程状态,那么您可以遍历_thread并中止:

 void DieDieDie() { foreach (Thread thread in _thread) { thread.Abort(); thread.Join(); // if you need to wait for the thread to die } } 

在你的情况下,你可能只是将它们全部中止并关闭,因为它们只是在进行计算。 但是,如果您需要等待数据库写入操作或需要关闭非托管资源,那么您需要捕获ThreadAbortException或发出线程信号以正常自杀。

你想要延迟线程取消,这基本上意味着线程终止自己,而不是线程管理器异步取消线程,这是更不明确和危险的。

我想比直接终止更优雅地处理线程取消,你可以使用线程外部事件触发的信号处理程序 – 也许是线程管理器。