带有非空元素的列表最终包含null。(List with non

编程入门 行业动态 更新时间:2024-10-28 20:29:03
带有非空元素的列表最终包含null。(List with non-null elements ends up containing null. A synchronization issue?)

首先,对于这个标题感到抱歉 - 我无法弄清楚那个简短而清楚的标题。

问题出在这里:我有一个列表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方法,即创建一个代理来处理线程继续运行代码的过程? 我知道我可以为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操作,我只需要这个进行调试(它不会在最终产品中),所以我只是想快速修复。

谢谢大家的答案。

First of all, sorry about the title -- I couldn't figure out one that was short and clear enough.

Here's the issue: I have a list List<MyClass> list to which I always add newly-created instances of MyClass, like this: list.Add(new MyClass()). I don't add elements any other way.

However, then I iterate over the list with foreach and find that there are some null entries. That is, the following code:

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

will sometimes throw an exception. I should point out that the list.Add(new MyClass()) are performed from different threads running concurrently. The only thing I can think of to account for the null entries is the concurrent accesses. List<> isn't thread-safe, after all. Though I still find it strange that it ends up containing null entries, instead of just not offering any guarantees on ordering.

Can you think of any other reason?

Also, I don't care in which order the items are added, and I don't want the calling threads to block waiting to add their items. If synchronization is truly the issue, can you recommend a simple way to call the Add method asynchronously, i.e., create a delegate that takes care of that while my thread keeps running its code? I know I can create a delegate for Add and call BeginInvoke on it. Does that seem appropriate?

Thanks.


EDIT: A simple solution based on Kevin's suggestion:

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); } } }

I only need to control Add operations and I just need this for debugging (it won't be in the final product), so I just wanted a quick fix.

Thanks everyone for your answers.

最满意答案

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

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

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

List<T> can only support multiple readers concurrently. If you are going to use multiple threads to add to the list, you'll need to lock the object first. There is really no way around this, because without a lock you can still have someone reading from the list while another thread updates it (or multiple objects trying to update it concurrently also).

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

Your best bet probably is to encapsulate the list in another object, and have that object handle the locking and unlocking actions on the internal list. That way you could make your new object's "Add" method asynchronous and let the calling objects go on their merry way. Any time you read from it though you'll most likely still have to wait on any other objects finishing their updates though.

更多推荐

本文发布于:2023-08-06 03:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1443575.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:元素   列表   List   null

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!