加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读