c# – 这是一个已知的线程安全的syched / locked模式吗?
发布时间:2020-12-15 21:36:15 所属栏目:百科 来源:网络整理
导读:我觉得我正在重新发明轮子,并且很有可能那里的人已经撞到了代码,并提出了一个良好,稳定且经过测试的模式来解决这个问题,我没有’我遇到了它. 我想出了以下似乎对我有用的解决方案. 它应该为处理应该以线程安全方式访问的对象提供一致的接口. @pst称这是一个
我觉得我正在重新发明轮子,并且很有可能那里的人已经撞到了代码,并提出了一个良好,稳定且经过测试的模式来解决这个问题,我没有’我遇到了它.
我想出了以下似乎对我有用的解决方案. @pst称这是一个“原子”对象获取/设置持有者,这是一种在别处使用的模式吗? 这是界面: public interface ISynched<T> { bool Read( ref T value ); bool Read( ref T value,TimeSpan timeout ); bool Write( T value ); bool Write( T value,TimeSpan timeout ); bool Do( Action<T> roAction ); bool Do( Action<T> roAction,TimeSpan timeout ); bool Do( Action<T,Action<T>> rwAction ); bool Do( Action<T,Action<T>> rwAction,TimeSpan timeout ); } 实施如下: public class Synched<T>: ISynched<T> { static public readonly TimeSpan Infinity = TimeSpan.FromMilliseconds(-1); private T _value; public static Synched<T> MakeSynched( T value ) { return new Synched<T>() { _value = value }; } private Synched() {} public bool Read( ref T value ) { return Read( ref value,Infinity ); } public bool Read( ref T value,TimeSpan timeout ) { var tmp = default(T); var success = Do( (v) => tmp = v,timeout ); if( success ) value = tmp; return success; } public bool Write( T value ) { return Do( (v,set) => set(v) ); } public bool Write( T value,TimeSpan timeout ) { return Do( (v,set) => set(v),timeout ); } public bool Do( Action<T> roAction ) { return Do( roAction,Infinity ); } public bool Do( Action<T> roAction,TimeSpan timeout ) { bool lockWasTaken = false; try { Monitor.TryEnter(this,timeout,ref lockWasTaken); if(!lockWasTaken) return false; roAction( _value ); return true; } finally { if (lockWasTaken) Monitor.Exit(this); } } public bool Do( Action<T,Action<T>> rwAction ) { return Do( rwAction,Infinity); } public bool Do( Action<T,ref lockWasTaken); if(!lockWasTaken) return false; rwAction( _value,value => _value = value ); return true; } finally { if (lockWasTaken) Monitor.Exit(this); } } } 还有一个额外的静态非泛型类,可以更容易地编写Synched对象的创建: public static class Synched { public static Synched<T> MakeSynched<T>( T value ) { return Synched<T>.MakeSynched( value ); } } 编辑:我已经改变了这个例子以使其更有意义 var synchedCol = Synched.MakeSynched( new List<SomeClass>() ); synchedCol.Do( c => { c.Add(new SomeClass()); c.Add(new SomeClass() { Property1 = "something" } ); } ); var i = 1; SomeClass val; synchedCol.Do( c => val = c[i] ); var i = 1; synchedCol.Do( c => { if( c[i].Property1 == "something" ) { c.Remove(c[i]); } }); 我在正确的轨道上吗?有没有人遇到类似的东西?是否有类似的现有模式? 解决方法
不要试图重新发明轮子
如果你想要一个线程安全的集合从System.Collections.Concurrent名称空间中选择一个. 例如,BlockingColletion< T>为实现IProducerConsumerCollection< T>的线程安全集合提供阻塞和绑定功能.这将比您的实现更高效,因为它实现了生产者/消费者(读/写)模式.这意味着读者不必同步,也不会互相阻塞. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |