我第一次尝试嵌入多线程,遇到了一些意想不到的问题,希望你能帮忙。
下面是给我带来麻烦的代码片段:
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
}
一旦调用了ProcessCollection方法,并且我试图迭代集合,我就会得到“底层列表中的范围无效”。
先谢了!
更新:伙计们,谢谢你们每一个人。通过应用你们的建议,我能够大大简化并让它工作。
3条答案
按热度按时间mrphzbgm1#
在这里使用
Interlocked.Increment
是不必要的,您希望局部变量idx
只被一个线程看到,这样就不需要加锁。当前您正在“关闭循环变量”,这意味着线程看到的是变量的最新值,而不是创建委托时的值。您希望其他线程接收此变量的 * 副本 *。这样,即使原始变量更改,这些副本也不会更改。
尝试将代码更改为:
相关问题:
相关文章:
xzlaal3s2#
你有几个问题。
我假设您已经省略了获取
batchCollection
然后定期从recordsCollection
中删除它们的代码,否则那里也会有问题。以下是您可以修复它的方法。
或者我的重构版本,据我所知,做了完全相同的事情...
mw3dktmi3#
你这是在玩火。你有一个开放的结局,看:http://en.wikipedia.org/wiki/Closure_(computer_science)
另外,如果只获取一个项目,为什么要使用getRange?
使用通用列表也会有所帮助。
如果我错了请纠正我,但是我认为您不再需要idx变量了。
另外,不要忘记异常是由调用堆栈引发的:http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
干杯!