C#并行读取访问List而不复制

时间:2016-08-09 10:32:57

标签: c# .net parallel-processing

考虑以下示例:

class Example
{
    private readonly List<string> _list = new List<string>();
    private readonly object _lock = new object();

    public IReadOnlyList<string> Contents
    {
        get
        {
            lock (_lock)
            {
                return new List<string>(_list);
            }
        }
    }

    public void ModifyOperation(string example)
    {
        lock (_lock)
        {
            // ...
            _list.Add(example);
            // ...
        }
    }
}

如何在不复制整个List的情况下实现对Contents列表的并行读取访问?在C#中有并发Collections,但没有线程安全列表。在Java中有类似CopyOnWriteArrayList

的东西

2 个答案:

答案 0 :(得分:6)

在我看来,ImmutableList<T>包中的System.Collections.Immutable类非常适合这种情况。它实现了IReadOnlyList<T>,因为它是不可变的,即从未修改过,所以你可以直接从读访问器返回它。所需的唯一同步将在修改操作之间:

class Example
{
    private ImmutableList<string> _list = ImmutableList<string>.Empty;
    private readonly object _lock = new object();

    public IReadOnlyList<string> Contents => _list;

    public void ModifyOperation(string example)
    {
        lock (_lock)
        {
            // ...
            _list = _list.Add(example);
            // ...
        }
    }
}

答案 1 :(得分:1)

无锁建议......

class Example
{
    private ImmutableList<String> _list = ImmutableList<String>.Empty;

    public IReadOnlyList<String> Contents { get { return _list; } }

    public void ModifyOperation(String example)
    {
        ImmutableList<String> original;
        ImmutableList<String> afterChange;
        do
        {
            original = _list;
            afterChange = _list.Add(example);
        }
        while (Interlocked.CompareExchange(ref _list, afterChange, original) != original);
    }
}