ade*_*825 4 .net c# synchronization list enumerators
我正在测试一些同步结构,我注意到一些困扰我的东西.当我在同时写入一个集合时枚举它时,它抛出了异常(这是预期的),但是当我使用for循环遍历集合时,它没有.有人可以解释一下吗?我认为List不允许读者和作者同时操作.我希望循环遍历集合以展示与使用枚举器相同的行为.
更新:这是一个纯粹的学术练习.我强调,如果列表同时写入列表是很糟糕的.我也明白我需要一个同步结构.我的问题是关于为什么一个操作会像预期的那样抛出一个异常,而另一个却没有.
代码如下:
class Program
{
private static List<string> _collection = new List<string>();
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(AddItems), null);
System.Threading.Thread.Sleep(5000);
ThreadPool.QueueUserWorkItem(new WaitCallback(DisplayItems), null);
Console.ReadLine();
}
public static void AddItems(object state_)
{
for (int i = 1; i <= 50; i++)
{
_collection.Add(i.ToString());
Console.WriteLine("Adding " + i);
System.Threading.Thread.Sleep(150);
}
}
public static void DisplayItems(object state_)
{
// This will not throw an exception
//for (int i = 0; i < _collection.Count; i++)
//{
// Console.WriteLine("Reading " + _collection[i]);
// System.Threading.Thread.Sleep(150);
//}
// This will throw an exception
List<string>.Enumerator enumerator = _collection.GetEnumerator();
while (enumerator.MoveNext())
{
string value = enumerator.Current;
System.Threading.Thread.Sleep(150);
Console.WriteLine("Reading " + value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*ell 15
枚举时不能修改集合.即使没有考虑线程问题,该规则也存在.来自MSDN:
只要集合保持不变,枚举器仍然有效.如果对集合进行了更改(例如添加,修改或删除元素),则枚举数将无法恢复,并且其行为未定义.
基于整数的for循环实际上不是枚举器.在大多数情况下,完成同样的事情.但是,IEnumerator的接口保证您可以遍历整个集合.如果在修改集合后发生对MoveNext的调用,则平台会通过抛出异常来内部强制执行此操作.枚举器对象抛出此异常.
基于整数的for循环仅通过其数字列表.当您按整数索引集合时,您只是将项目放在该位置.如果已从列表中插入或删除某些内容,您可以跳过某个项目或两次运行相同的项目.当您需要在遍历集合时修改集合时,这在某些情况下非常有用.for循环没有枚举器对象来保证IEnumerator契约,因此不会抛出异常.