在C#中不使用锁定的多个并发读取器

时间:2013-12-20 10:46:31

标签: c# .net multithreading

我在下面创建了一个示例程序。在这个程序中,我期待两件事没有锁

  1. 我必须覆盖ToString()方法,此方法应该支持并发读者。
  2. 它应该是线程安全的
  3. using System.Collections.Generic;
    using System.Linq;
    
    namespace Second.App
    {
        class Program
        {
            static void Main(string[] args)
            {
                var sampleClass=new SampleClass();
                sampleClass.AddString("Apple");
                sampleClass.AddString("Orange");
                string allStr =  sampleClass.ToString();
            }
        }
        public class SampleClass:SecondClass
        {
            public override void AddString(string text)
            {
                base.AddString(text);
            }
            public override string ToString()
            {
                return base.ToString();
            }
        }
        public  class SecondClass
        {
            private readonly List<string> _collection = new List<string>();
            public virtual void AddString(string text)
            {
                _collection.Add(text);
            }
    
            public override string ToString()
            {
                const string delimiter = ",";
                return _collection.Aggregate((i, j) => i + delimiter + j);
            }
        }
    }
    

    希望得到一些好的答案..

3 个答案:

答案 0 :(得分:1)

System.Threading.ReaderWriterLockSlim会做你需要的。

  

使用ReaderWriterLockSlim保护读取的资源   多个线程,一次由一个线程写入。   ReaderWriterLockSlim允许多个线程处于读取模式,   允许一个线程处于写入模式,具有独占所有权   锁定,并允许一个具有读访问权限的线程可以升级   读取模式,线程可以从中升级到写入模式   必须放弃对资源的读访问权。

我非常确定ReaderWriterLockSlim尝试通过旋转短锁并提升为互斥锁以获得更长的锁来避免操作系统级互斥(lock使用这些互斥锁。

答案 1 :(得分:1)

您可以通过缓存折叠的字符串来优化单个编写器和多个并发读取器的性能。并发读者可能获得陈旧的字符串,但赋值将是原子的。但是,如果您有多个作家,则需要同步。

public  class SecondClass
{
    private readonly List<string> _collection = new List<string>();
    private string _lastFoldedString;
    private const string delimiter = ",";

    public virtual void AddString(string text)
    {
        // You'll need some synchronization type if more than one concurrent writer
        // lock(_collection)
        {
           _collection.Add(text);
           // Or Use String.Join, or just have a running appender
           _lastFoldedString = _collection.Aggregate((i, j) => i + delimiter + j);
        }
    }

    public override string ToString()
    {
        return _lastFoldedString;
    }
}

答案 2 :(得分:0)

有各种可以处理并发访问的集合类,例如:在System.Collections.Concurrent命名空间中。

但是它们本身都是锁定的。还有什么方法可以处理并发访问?