.NET ArrayList 并行处理
我第一次尝试嵌入多线程并遇到一些意想不到的问题,希望你能提供帮助。
这是给我带来麻烦的代码片段:
ArrayList recordsCollection = new ArrayList();
ArrayList batchCollection = null;
int idx = 0;
while(true)
{
// Some code to generate and assign new batchCollection here
recordsCollection.Add(batchCollection);
ThreadPool.QueueUserWorkItem(delegate
{
ProcessCollection(recordsCollection.GetRange(idx, 1));
});
Interlocked.Increment(ref idx);
}
private void ProcessCollection(ArrayList collection)
{
// Do some work on collection here
}
调用 Process Collection 方法并且我尝试迭代集合时,我收到“基础列表中的范围无效”。
提前致谢!
更新:伙计们,谢谢你们每一个人。通过采纳您的建议,我能够大大简化并使其发挥作用。
I am attempting at embedding multi-threading for the first time ever and running into some unexpected issues, hope you can help.
Here's the code fragment that gives me troubles:
ArrayList recordsCollection = new ArrayList();
ArrayList batchCollection = null;
int idx = 0;
while(true)
{
// Some code to generate and assign new batchCollection here
recordsCollection.Add(batchCollection);
ThreadPool.QueueUserWorkItem(delegate
{
ProcessCollection(recordsCollection.GetRange(idx, 1));
});
Interlocked.Increment(ref idx);
}
private void ProcessCollection(ArrayList collection)
{
// Do some work on collection here
}
Once the Process Collection method is invoked and I am attempting to iterate through collection I am getting "The range in the underlying list is invalid".
Thanks in advance!
Update: Guys, thank you to each and every one of you. Through applying your suggestions I was able to greatly simplify and get it to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
此处没有必要使用
Interlocked.Increment
。您希望局部变量 idx 只能被一个线程看到,因此不需要锁定。目前,您正在“关闭循环变量”,这意味着线程看到的是变量的最新值,而不是创建委托时的值。您希望其他线程接收此变量的副本。即使原始变量发生变化,这些副本也不会改变。
尝试将代码更改为:
相关问题:
相关文章:
Your use of
Interlocked.Increment
here is unnecessary. You want that the local variableidx
is only be seen by one thread so there is no need to lock.Currently you are "closing over the loop variable" which means that the threads see the latest value of the variable rather than the value at the time the delegate was created. You want the other threads to receive copies of this variable. These copies will then not change even if the original variable changes.
Try changing your code to this:
Related question:
Related article:
你有几个问题。
我假设您省略了获取
batchCollection
的代码,然后为了简洁起见定期从recordsCollection
中删除它们,否则也会出现问题。以下是修复方法。
或者我的重构版本,据我所知,它做了完全相同的事情......
You have a couple of problems.
I am assuming you have omitted the code for acquiring a
batchCollection
and then periodically removing them fromrecordsCollection
for brevity, otherwise there would be issues there as well.Here is how you can fix it.
Or my refactored version which, as best I can tell anyway, does the exact same thing...
你在这里玩火。
您有一个开放的闭包,请参阅:http://en.wikipedia.org/wiki/Closure_ (computer_science)
另外,如果您只获取一项,为什么还要使用 getRange ?
使用通用列表也可能有所帮助。
如果我错了,请纠正我,但我认为您不再需要 idx 变量。
另外,不要忘记异常是由调用堆栈引发的: http://www .codeproject.com/KB/architecture/exceptionbestpractices.aspx
干杯!
You are playing with fire here.
You got an open closure, see : http://en.wikipedia.org/wiki/Closure_(computer_science)
Also, why you use getRange if you are only getting one item ?
Using a generic list could also help.
Correct me if i'm wrong, but I do not think you will need the idx variable anymore.
Also, don't forget that exceptions are throw on by call stack : http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
Cheers !