gpt4 book ai didi

c# - 这是已知的线程安全同步/锁定模式吗?

转载 作者:行者123 更新时间:2023-11-30 12:49:39 25 4
gpt4 key购买 nike

我觉得我是在重新发明轮子,很有可能已经有人用脑袋敲代码并想出了一个好的、稳定的和经过测试的模式来解决这个问题,并且我还没遇到过。

我想出了以下似乎现在对我有用的解决方案。
它应该提供一个一致的接口(interface)来处理应该以线程安全方式访问的对象。

@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, Action<T>> rwAction, TimeSpan timeout )
{
bool lockWasTaken = false;
try
{
Monitor.TryEnter(this, timeout, ref lockWasTaken);
if(!lockWasTaken) return false;

rwAction( _value, value => _value = value );
return true;
}
finally
{
if (lockWasTaken) Monitor.Exit(this);
}
}
}

还有一个额外的静态非泛型类,可以更轻松地编写同步对象创建代码:

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> 的线程安全集合提供阻塞和边界功能.这将比您的实现更高效,因为它实现了生产者/消费者(读者/作者)模式。这意味着阅读器不必同步并且不会相互阻塞。

关于c# - 这是已知的线程安全同步/锁定模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11166073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com