.NET中简单的线程安全列表对象< 4需要

时间:2011-09-19 10:53:59

标签: c# multithreading

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

在.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-object可以尽可能简单 - 任何类型的列表都能够以线程安全的方式填充字符串。

1 个答案:

答案 0 :(得分:1)

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

E.g。

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 ...

}

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

E.g。

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