我们在多线程上下文中调用(线程安全的)静态方法,但需要将返回的错误消息添加到某种列表中。
在.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可以尽可能简单 - 任何类型的列表都能够以线程安全的方式填充字符串。
答案 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);
}
}