加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 00:13:28 所属栏目:百科 来源:网络整理
导读:首先,对标题感到抱歉 – 我无法弄清楚那个短而清晰的标题. 这是问题:我有一个列表List MyClass我总是添加新创建的MyClass实例的列表,如下所示:list.Add(new MyClass()).我不以任何其他方式添加元素. 然而,然后我用foreach迭代列表并发现有一些空条目.也就
首先,对标题感到抱歉 – 我无法弄清楚那个短而清晰的标题.

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

然而,然后我用foreach迭代列表并发现有一些空条目.也就是说,以下代码:

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

有时会抛出异常.
我应该指出list.Add(new MyClass())是从并发运行的不同线程执行的.我能想到的唯一考虑空条目的是并发访问.列表与LT;>毕竟,这不是线程安全的.虽然我仍然觉得奇怪的是它最终包含空条目,而不仅仅是在订购时没有提供任何保证.

你能想到其他任何原因吗?

此外,我不关心添加项目的顺序,我不希望调用线程阻止等待添加其项目.如果同步确实是问题,你能推荐一种简单的方法来异步调用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);
        }
    }
}

我只需要控制Add操作,我只需要这个用于调试(它不会在最终产品中),所以我只想快速修复.

谢谢大家的回答.

解决方法

列表与LT; T>只能同时支持多个读者.如果要使用多个线程添加到列表中,则需要先锁定对象.实际上没有办法解决这个问题,因为如果没有锁定,你仍然可以让某人从列表中读取而另一个线程更新它(或者多个对象同时尝试更新它).

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读