我正在使用异步网络调用的c#中编写程序。其中一些修改了一个集合,程序的其余部分不时循环。问题是,当异步调用在循环期间尝试修改为集合时,会抛出异常并且程序崩溃。
我对这种类型的编程很新,这似乎是一个应该有标准解决方案的常见问题。
我尝试的是设置一个bool,在循环访问集合并检查异步方法之前我将其关闭。如果它没有打开,我修改了一个不同的集合,并根据该程序的其余部分对原始集合进行更改。问题是异步方法在这个集合上也有一个循环,所以当它被连续快速调用时,它会干扰那个循环。
我认为更好的解决方案是设置代码,以便当bool表示集合不安全修改时,任何这些调用都会被延迟。但是,我不知道这是否是一个足够好的解决方案(因为我认为异步调用可能首先开始,然后程序可能会进入不安全的部分)。
这不是实际的程序,而是为了清楚起见问题的一个例子:
private List<Stuff> myList = new List();
private void NetworkDataReceived(Stuff s)
{
myList.Add(s);
}
private void SomeOtherMethod()
{
foreach(Stuff s in myList)
{
DoSomethingWithStuff(s);
}
}
在上面的示例中,当SomeOtherMethod也在运行时调用NetworkDataReceived时,程序崩溃并出现以下InvalidOperationException:&#34; Collection已被修改;枚举操作可能无法执行。&#34;
如果在C#中有这种编程经验的人能给我一个指向如何解决这个问题的指示,我会很感激。
答案 0 :(得分:1)
List<T>
不是线程安全的,所以你不能让多个线程在同一时间读取和写入它。
您可以使用.NET框架提供的thread-safe collections之一来执行此操作。这种集合的一个例子是ConcurrentQueue<T>
类。
引自上述参考文献:
多个线程可以安全有效地添加或删除这些集合中的项目,而无需在用户代码中进行额外的同步。