Let’s say I have a list in a class which will be used in a multi threading scenario.
public class MyClass
{
List<MyItem> _list= new List<MyItem>();
protected object SyncRoot {
get {
return ((IList)_list).SyncRoot;
}
}
public void Execute1()
{
lock(SyncRoot)
{
foreach(var item in _list) DoSomething(item);
}
}
public void Execute2()
{
Item[] list;
lock(SyncRoot)
{
list=_list.ToArray();
}
for(var i=0;i<list.Length;i++) DoSomething(list[i]);
}
}
The method Execute1 is the ‘normal’ way to enumerate the list in a thread-safe way. But what about Execute2? Is this approach still thread-safe?
It’s safe as long as every other use of
_listis also protected with the samelockstatement. You are taking exclusive access to the list, copying its contents and then working on the copy (to which you also have exclusive access due to scoping). A bit wasteful at first sight, but a legitimate approach under certain circumstances.