gpt4 book ai didi

c# - 在多个线程中处理列表时的空引用

转载 作者:行者123 更新时间:2023-11-30 22:25:14 26 4
gpt4 key购买 nike

基本上,我有一个对象集合,我将它分成小集合,并同时在每个小集合上的线程上做一些工作。

int totalCount =  SomeDictionary.Values.ToList().Count;
int singleThreadCount = (int)Math.Round((decimal)(totalCount / 10));
int lastThreadCount = totalCount - (singleThreadCount * 9);

Stopwatch sw = new Stopwatch();

Dictionary<int,Thread> allThreads = new Dictionary<int,Thread>();
List<rCode> results = new List<rCode>();

for (int i = 0; i < 10; i++)
{
int count = i;

if (i != 9)
{
Thread someThread = new Thread(() =>
{
List<rBase> objects = SomeDictionary.Values
.Skip(count * singleThreadCount)
.Take(singleThreadCount).ToList();

List<rCode> result = objects.Where(r => r.ZBox != null)
.SelectMany(r => r.EffectiveCBox, (r, CBox) => new rCode
{
RBox = r,
// A Zbox may refer an object that can be
// shared by many
// rCode objects even on different threads
ZBox = r.ZBox,
CBox = CBox
}).ToList();

results.AddRange(result);
});

allThreads.Add(i, someThread);
someThread.Start();
}
else
{
Thread someThread = new Thread(() =>
{
List<rBase> objects = SomeDictionary.Values
.Skip(count * singleThreadCount)
.Take(lastThreadCount).ToList();

List<rCode> result = objects.Where(r => r.ZBox != null)
.SelectMany(r => r.EffectiveCBox, (r, CBox) => new rCode
{
RBox = r,
// A Zbox may refer an object that
// can be shared by many
// rCode objects even on different threads
ZBox = r.ZBox,
CBox = CBox
}).ToList();

results.AddRange(result);
});

allThreads.Add(i, someThread);
someThread.Start();
}
}

sw.Start();
while (allThreads.Values.Any(th => th.IsAlive))
{
if (sw.ElapsedMilliseconds >= 60000)
{
results = null;
allThreads.Values.ToList().ForEach(t => t.Abort());
sw.Stop();
break;
}
}

return results != null ? results.OrderBy(r => r.ZBox.Name).ToList():null;

所以,我的问题是,有时,我在返回结果之前执行 OrderBy 操作时遇到空引用异常,我无法确定异常到底在哪里,我按回,单击执行此操作的同一个按钮再次对相同的数据进行操作,并且有效! .. 如果有人可以帮助我确定这个问题,我将不胜感激。注意:Zbox 可能引用一个对象,即使在不同的线程上也可以由许多 rCode 对象共享,这可能是问题所在吗?因为我无法在测试时确定这一点,因为发生的错误是不确定的。

最佳答案

尽管我不同意该答案,但在所选答案中正确找到了错误。您应该切换到使用并发集合。在您的情况下是 ConcurrentBag 或 ConcurrentQueue。其中一些(部分)无锁以获得更好的性能。而且它们提供了更多的可读性和更少的代码,因为您不需要手动锁定。

如果您避免手动创建线程和手动分区,您的代码的大小也会减少一半以上,可读性也会提高一倍;

Parallel.ForEach(objects, MyObjectProcessor);

public void MyObjectProcessor(Object o)
{
// Create result and add to results
}

如果您想使用 Parallel.ForEach 限制线程数,请使用 ParallelOptions 对象......

关于c# - 在多个线程中处理列表时的空引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12421839/

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