【问题标题】:Simple thread-safe list object in .NET < 4 needed.NET 中的简单线程安全列表对象 < 4 需要
【发布时间】:2011-09-19 10:53:58
【问题描述】:

我们在多线程上下文中调用(线程安全)静态方法,但需要将返回的错误消息添加到某种列表中。

在 .NET 4 中,可以使用 ConcurrentDictionary。但是,如果我需要在 3.5 中运行它,下面的 allMessages 对象有什么替代方法?

 using (var mre = new ManualResetEvent(false))
 {
     for (int i = 0; i < max1; i++)
     {
          ThreadPool.QueueUserWorkItem(st =>
          {
            for (int j = 0; j < max2; j++)
            {
                string errorMsg;
                // Call thread-safe static method
                SomeStaticClass.SomeStaticMethod(out errorMsg);

                // Need to collect all errorMsg in some kind of threadsafe list
                // allMessages.Add(errorMsg);

             }
             if (Interlocked.Decrement(ref pending) == 0) mre.Set();
           });
    }
    mre.WaitOne();
 }

allMessages 对象可以尽可能简单 - 任何能够以线程安全方式填充字符串的列表都可以。

【问题讨论】:

  • 使用普通的收集和锁定怎么样?
  • 如果我使用任何私有对象 thisLock = new Object();并做 lock(thisLock) {allMessages.Add(errorMsg);},这样就够了吗?
  • 如果这是您访问字典的唯一方式(阅读和写作),那么这就足够了。

标签: c# multithreading


【解决方案1】:

您可以编写自己的ICollection&lt;T&gt; 接口实现,您只需将所有调用委托给List&lt;T&gt; 类型的私有成员,用锁保护每个访问。

例如

public class LockedCollection<T> : ICollection<T>
{
   private readonly object _lock = new object();
   private readonly List<T> _list = new List<T>();

   public void Add(T item)
   {
      lock (_lock)
      {
         _list.Add(item);
      }
   }

   // other members ...

}

如果这值得“努力”(以及要维护的代码),那就是您需要决定的问题。您可以使用锁/监视器保护您对“普通”列表的调用。

例如

            for (int j = 0; j < max2; j++)
            {
                string errorMsg;
                // Call thread-safe static method
                SomeStaticClass.SomeStaticMethod(out errorMsg);

                lock (allMessageLock) // allMessagesLock is an "object", defined with the same lifetime (static- or instance-member) as "allMessages".
                {
                   // Need to collect all errorMsg in some kind of threadsafe list
                   allMessages.Add(errorMsg);
                }
            }

【讨论】:

  • 谢谢。似乎没有太多的努力。会试一试的。
  • 只是为了扩展 Christian 的答案,您可能希望使用 ReaderWriterLockSlim 而不是简单的锁来尽可能快地从集合中读取,同时仍确保写入是线程安全的
猜你喜欢
  • 2011-04-28
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
相关资源
最近更新 更多