gpt4 book ai didi

c# - 包含非 null 元素的列表最终包含 null。同步问题?

转载 作者:太空狗 更新时间:2023-10-30 00:09:11 24 4
gpt4 key购买 nike

首先,对于标题感到抱歉 -- 我想不出一个足够简短和清晰的标题。

问题是:我有一个列表 List<MyClass> list我总是向其中添加新创建的 MyClass 实例,像这样:list.Add(new MyClass()) .我不会以任何其他方式添加元素。

但是,然后我用 foreach 遍历列表并发现有一些空条目。即如下代码:

foreach (MyClass entry in list)
if (entry == null)
throw new Exception("null entry!");

有时会抛出异常。我应该指出 list.Add(new MyClass())从同时运行的不同线程执行。我唯一能想到的解释 null条目是并发访问。 List<>毕竟不是线程安全的。虽然我仍然觉得它最终包含空条目很奇怪,而不是不提供任何订购保证。

你能想到其他原因吗?

另外,我不关心项目的添加顺序,我不希望调用线程阻塞等待添加他们的项目。如果同步确实是问题,你能推荐一种简单的方法来调用 Add异步方法,即创建一个委托(delegate)来处理它,而我的线程继续运行它的代码?我知道我可以为 Add 创建一个委托(delegate)并调用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);
}
}
}

我只需要控制Add操作,我只需要它来调试(它不会出现在最终产品中),所以我只想快速修复。

感谢大家的回答。

最佳答案

List<T>只能同时支持多个读者。如果您打算使用多个线程来添加到列表中,则需要先锁定该对象。确实没有办法解决这个问题,因为如果没有锁,您仍然可以让某人从列表中读取,而另一个线程更新它(或者多个对象也试图同时更新它)。

http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

最好的办法可能是将列表封装在另一个对象中,并让该对象处理内部列表上的锁定和解锁操作。这样您就可以使新对象的“Add”方法异步化,并让调用对象继续它们的快乐方式。任何时候你从它读取你很可能仍然需要等待任何其他对象完成它们的更新。

关于c# - 包含非 null 元素的列表最终包含 null。同步问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2713699/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com