本文实例讲述了C#线程同步的三类情景,。具体分析如下:
C# 已经提供了我们几种非常好用的类库如 BackgroundWorker、Thread、Task等,借助它们,我们就能够分分钟编写出一个多线程的应用程序。
比如这样一个需求:有一个 Winform 窗体,点击按钮后,会将窗体中的数据导出到一个 output.pdf 文件中。原先的代码没有采用多线程技术,所以当点击按钮后,整个窗体就变成无响应了。为了解决这个问题,可以使用 Task.Run(()=>{...导出文件的代码});
上面的代码看似简单,却隐藏着种种危机。如果在导出的期间,窗体的数据被修改了,那会怎么样?如果多个窗体同时导出到同一个文件,又会怎么样?
在看完本系列后,你就会清楚了。
有点了解的朋友都知道线程同步有多种手段,什么 mutex、moniter、seamphore、event 等等,我把它们归为三类,对应三种需要线程同步的情景。
情景一:此茅坑有主了
当一个资源同时被多个线程访问时,有可能会造成资源冲突(尤其是在存在多个写线程的时候)的情景。遇到这种情况,在 C# 中,我们可以使用 Interlocked、lock、Moniter、SpinLock、ReadWriteLockSlim、Mutex 来处理问题。
什么情况下会被认为是情景一?
当你设计的类中出现静态变量、IO操作时,就会遇到情景一。因为这些资源是由多个对象共享的,不同的线程很同时去访问这些资源时,就可能会出现争用。
当一个类被设计成单例,且包含实例变量时,也会遇到情景一。因为实例变量属于这个单例,当多个线程操纵此单例时,该变量可能会被争用。
当一个类中的方法调用线程操作某个实例变量时,也会遇到情景一。
情景二:数量有限,先到先得
情景一强调的是一对多的情形,而在情景二中,资源的数量并不唯一。相比于情景一,情景二侧重的是数量上的限制。而用于实现这一需求的类有:Semaphore、SemaphoreSlim。










