Ali*_*lix 4 c# null synchronization asynchronous list
首先,对标题感到抱歉 - 我无法弄清楚那个短而清晰的标题.
这是问题:我有一个列表List<MyClass> list,我总是添加新创建的实例MyClass,如下所示:list.Add(new MyClass()).我不以任何其他方式添加元素.
但是,然后我遍历列表foreach并发现有一些空条目.也就是说,以下代码:
foreach (MyClass entry in list)
if (entry == null)
throw new Exception("null entry!");
Run Code Online (Sandbox Code Playgroud)
有时会抛出异常.我应该指出,这些list.Add(new MyClass())是从同时运行的不同线程执行的.我能想到的唯一考虑null条目的是并发访问.List<>毕竟,这不是线程安全的.虽然我仍然觉得奇怪的是它最终包含空条目,而不是在订购时不提供任何保证.
你能想到其他任何原因吗?
此外,我不关心添加项目的顺序,我不希望调用线程阻止等待添加其项目.如果同步确实是问题,你能推荐一种简单的方法来Add异步调用该方法,即创建一个委托,在我的线程继续运行其代码时处理它吗?我知道我可以创建一个代表Add并调用BeginInvoke它.这看起来合适吗?
谢谢.
编辑:一个基于凯文的建议的简单解决方案:
public class AsynchronousList<T> : List<T> {
private AddDelegate addDelegate;
public delegate void AddDelegate(T item);
public AsynchronousList() {
addDelegate = new AddDelegate(this.AddBlocking);
}
public void AddAsynchronous(T item) {
addDelegate.BeginInvoke(item, null, null);
}
private void AddBlocking(T item) {
lock (this) {
Add(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我只需要控制Add操作,我只需要这个用于调试(它不会在最终产品中),所以我只想快速修复.
谢谢大家的回答.
List<T>只能同时支持多个读者.如果要使用多个线程添加到列表中,则需要先锁定对象.实际上没有办法解决这个问题,因为没有锁定,你仍然可以让某人从列表中读取而另一个线程更新它(或者多个对象同时尝试更新它).
http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
您最好的选择可能是将列表封装在另一个对象中,并使该对象处理内部列表上的锁定和解锁操作.这样你就可以使你的新对象的"添加"方法异步,让调用对象以他们的快乐方式运行.任何时候你读它虽然你很可能仍然需要等待任何其他对象完成他们的更新.