C# 我应该插入记忆载体吗?
我有这样的代码:C# 我应该插入记忆载体吗?,c#,multithreading,C#,Multithreading,我有这样的代码: ..... private volatile bool _connSharedDisposed; ...... // Thread 1 while (!_connSharedDisposed) { Thread.Sleep(1); } CGate.Close(); ...... // Thread 2 _connShared.Close(); _listenerFutInfo.Close
.....
private volatile bool _connSharedDisposed;
......
// Thread 1
while (!_connSharedDisposed)
{
Thread.Sleep(1);
}
CGate.Close();
......
// Thread 2
_connShared.Close();
_listenerFutInfo.Close();
_listenerFutInfo.Dispose();
_listenerFutCommon.Close();
_listenerFutCommon.Dispose();
_connShared.Dispose();
// insert Thread.MemoryBarrier here?
_connSharedDisposed = true;
我担心在调用\u connSharedDisposed.Dispose()
之前,\u connSharedDisposed=true
可能会重新排列并接收true
。可能吗?如果我的代码不起作用,如何修复它?我想我可能应该插入MemoryBarrier来阻止“重排”
另外,我可能应该使用
AutoResetEvent
而不是bool volatile
variable…如果您已声明\u conshareddisposed
与volatile
一起使用,则无需使用内存载体
volatile
使对字段的每次写入都成为volatile写入,对字段的每次读取都成为volatile读取。这意味着编译器不能对指令重新排序,以便访问字段的顺序彼此保持相同
在x86以外的处理器上,volatile
也会导致任何CPU缓存写入刷新到RAM。如果您为x86编译,那么volatile
仅适用于编译器优化
如果您试图做的是使单个线程进入等待状态,直到发生某些事情,那么可以使用自动重置事件AutoResetEvent
是对此进行建模的类。如果您想让多个线程停止等待,手动重置事件可能是更好的选择ManualResetEvent
或ManualResetEventSlim
(在.NET 4.0或更高版本中)是为其建模的类。而Thread.Sleep()
是反模式,您不应该这样做。您不能从线程2调用CGate.Close()
?如果没有,您可能应该使用一些同步原语,如ManualResetEventSlim
。编辑:没有读你的最后一段。@s请注意,在现实世界中,我有更复杂的条件,比如而(!\u connSharedDisposed | | |!connTransactionDispose | | |!connformodposed)
当多个线程中的多个条件都满足时,我如何引发事件?有几种方法可以做到这一点。靠近代码的是使用Monitor.Wait()
而不是sleep,然后在任何变量发生变化时调用Monitor.Pulse()
。另一个选项是使用类似于WaitHandle.WaitAll()
(或Task.Wait()
,您可以使用TaskCompletionSource
将Task
用作同步构造)。