Simple thread-safe list object in .NET < 4 needed
We call a (thread-safe) static method in a multi-threaded context, but need to add returned error messages to some sort of list.
In .NET 4, a ConcurrentDictionary could be used.开发者_如何转开发 But what is an alternative for the allMessages object below if I need to run this in 3.5?
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();
}
The allMessages-object can be as simple as possible - any kind of list would do that is capable of being filled with strings in a thread-safe manner.
You could write your own implementation of the ICollection<T>
interface, where you just delegate all calls to an private member of type List<T>
, protecting every access with lock.
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 ...
}
If that is worth the "effort" (and code to maintain), is the question you need to decide. You could just protect your calls to a "plain" List with a lock/monitor.
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);
}
}
精彩评论