.NET 4.0 C#中的并发读者

时间:2011-11-12 03:58:18

标签: c# .net concurrency

我在编程竞赛中遇到了这个难题,我不应该使用任何内置的并发.NET 4.0数据结构。

我必须覆盖ToString()方法,此方法应该支持并发读者。

这是我提出的解决方案,但我坚信它不支持 并发读者 。如何在不锁定列表的情况下支持并发读者?

class Puzzle
{
    private List<string> listOfStrings = new List<string>();

    public void Add(string item)
    {
        lock (listOfStrings)
        {
            if (item != null)
            {
                listOfStrings.Add(item);
            }
        }
    }

    public override string ToString()
    {
        lock (listOfStrings)
        {
            return string.Join(",", listOfStrings);
        }
    }
}

2 个答案:

答案 0 :(得分:8)

因为List<T>只是一个T[],所以从多个线程中读取列表并不安全。您的问题是读取时写入并发写入是不安全的。因此,您应该使用ReaderWriterLockSlim

class Puzzle
{
    private List<string> listOfStrings = new List<string>();
    private ReaderWriterLockSlim listLock = new ReaderWriterLockSlim();

    public void Add(string item)
    {
        listLock.EnterWriteLock();

        try
        {
            listOfStrings.Add(item);
        }
        finally
        {
            listlock.ExitWriteLock();
        }
    }

    public override string ToString()
    {
        listLock.EnterReadLock();

        try
        {
            return string.Join(",", listOfStrings);
        }
        finally
        {
            listLock.ExitReadLock();
        }
    }
}

ReaderWriterLockSlim将允许多个线程以读取模式进入锁定状态,但是如果/在某些情况下锁定处于写入模式时它们将全部阻塞。同样,在写入模式下进入锁定将阻塞,直到所有线程都以读取模式退出锁定。实际的外部工作是只要没有写入就可以同时进行多次读取,只要没有任何内容正在读取,就可以一次发生一次写入操作。

答案 1 :(得分:0)

因为它看起来不像删除不是一个要求,为什么你不能只返回一个字符串?

class Puzzle
{
    private string Value { get; set; }

    public Puzzle()
    {
        Value = String.Empty;
    }
    public void Add(String item)
    {
        Value += "," + item;
    }

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