c#对List的并行读访问,无需复制

本文关键字:复制 读访问 并行 List | 更新日期: 2023-09-27 18:01:32

考虑以下示例:

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 List的并行读访问?在c#中有并发的Collections,但是没有线程安全的List。在Java中有类似CopyOnWriteArrayList的东西

c#对List的并行读访问,无需复制

我认为System.Collections.Immutable包中的ImmutableList<T>类非常适合这种情况。它实现了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);
            // ...
        }
    }
}

无锁建议…

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);
    }
}