多线程的最佳实践

还是那句话,多线程很有用,但并非那么好玩。请使用之前确认你真的掌握了它们

 

本文请参考:http://msdn.microsoft.com/zh-cn/library/1c9txz50.aspx

有关重点摘录如下

  • 不要使用 Thread..::.Abort 终止其他线程。对另一个线程调用 Abort 无异于引发该线程的异常,也不知道该线程已处理到哪个位置。

  • 不要使用 Thread..::.SuspendThread..::.Resume 同步多个线程的活动。请使用 MutexManualResetEventAutoResetEventMonitor

  • 不要从主程序中控制辅助线程的执行(如使用事件),而应在设计程序时让辅助线程负责等待任务,执行任务,并在完成时通知程序的其他部分。如果辅助线程不阻止,请考虑使用线程池线程。Monitor..::.PulseAll 在辅助线程阻止的情况下很有用。

  • 不要将类型用作锁定对象。例如,避免在 C# 中使用 lock(typeof(X)) 代码,或在 Visual Basic 中使用 SyncLock(GetType(X)) 代码,或将 Monitor..::.EnterType 对象一起使用。对于给定类型,每个应用程序域只有一个 System..::.Type 实例。如果您锁定的对象的类型是 public,您的代码之外的代码也可锁定它,但会导致死锁。有关其他信息,请参见可靠性最佳做法

  • 锁定实例时要谨慎,例如,C# 中的 lock(this) 或 Visual Basic 中的 SyncLock(Me)。如果您的应用程序中不属于该类型的其他代码锁定了该对象,则会发生死锁。

  • 一定要确保已进入监视器的线程始终离开该监视器,即使当线程在监视器中时发生异常也是如此。C# 的 lock 语句和 Visual Basic 的 SyncLock 语句可自动提供此行为,它们用一个 finally 块来确保调用 Monitor..::.Exit。如果无法确保调用 Exit,请考虑将您的设计更改为使用 Mutex。Mutex 在当前拥有它的线程终止后会自动释放。

  • 一定要针对那些需要不同资源的任务使用多线程,避免向单个资源指定多个线程。例如,任何涉及 I/O 的任务都会从其拥有其自己的线程这一点得到好处,因为此线程在 I/O 操作期间将阻止,从而允许其他线程执行。用户输入是另一种可从专用线程获益的资源。在单处理器计算机上,涉及大量计算的任务可与用户输入和涉及 I/O 的任务并存,但多个计算量大的任务将相互竞争。

  • 对于简单的状态更改,请考虑使用 Interlocked 类的方法,而不是 lock 语句(在 Visual Basic 中为 SyncLock)。lock 语句是一个优秀的通用工具,但是 Interlocked 类为必须是原子性的更新提供了更好的性能。如果没有争夺,它会在内部执行一个锁定前缀。

  • posted @ 2010-03-14 06:18  陈希章  阅读(884)  评论(0编辑  收藏  举报