这是我对这个问题的看法,并试图在一个答案中提供一个准完整清单。如果遇到其他问题,我将不时编辑我的答案。
普遍认为会引起隐性障碍的机制:
- 所有
Monitor
类方法,包括C#关键字lock
- 所有
Interlocked
类方法。 - 所有
Volatile
类方法(.NET 4.5+)。 - 大多数
SpinLock
方法包括Enter
和Exit
。 Thread.Join
Thread.VolatileRead
和Thread.VolatileWrite
Thread.MemoryBarrier
- 该
volatile
关键字。 - 启动一个线程或导致一个代表到另一个线程上执行包括任何
QueueUserWorkItem
,Task.Factory.StartNew
,Thread.Start
,编译器提供的BeginInvoke
方法等 - 使用信令机制,诸如
ManualResetEvent
,AutoResetEvent
,CountdownEvent
,Semaphore
,Barrier
,等。 - 使用编组 *** 作,如
Control.Invoke
,Dispatcher.Invoke
,SynchronizationContext.Post
,等。
推测(但不确定)导致隐式障碍的机制:
Thread.Sleep
(由我本人提出,也可能是其他人提出的,因为使用这种方法可以解决存在内存障碍问题的代码)Thread.Yield
Thread.SpinWait
Lazy<T>
取决于LazyThreadSafetyMode
指定
其他值得注意的提及:
- C#中事件的默认添加和删除处理程序,因为它们使用
lock
或Interlocked.CompareExchange
。 - x86商店具有发布围栏语义
- 尽管ECMA规范没有强制性规定,但Microsoft对CLI的实现已在写入时释放了篱笆语义。
MarshalByRefObject
似乎抑制了子类中的某些优化,这可能使其看起来好像存在隐式内存屏障。感谢Hans Passant发现此问题并将其引起我的注意。1个
1
这说明了为什么BackgroundWorker
不用属性volatile
的基础字段即可正确工作的原因CancellationPending
。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)