我很难解决这个问题。
代码应该从文件对话框中导入图像。并且应该处理每个图像并将其发送到正确的类。 处理器是一个检测形状的类,所以基本上我发送每个图像并检测其中的形状(在类处理器中过滤到某个标准)
newList将获得图像中所有形状的中心。
我对Parallelism知之甚少,而我似乎无法想出如何解决这个问题。 请记住,我不需要将任何内容从一次迭代传递到另一次迭代。我只想一次处理和修正图像,整个操作分为线程。
我每次迭代都是独立的,我不需要从一次迭代返回到另一次迭代。
目前问题是从类正确返回的结果有时是不正确的。我想这是因为处理器和newList也必须是本地的?如果是,我该如何解决这个问题?如果不是我哪里出错了?
另请注意,使用普通的foreach可以正常使用
这是我的代码:
Parallel.ForEach(ofd.FileNames,
(file) =>
{
Image exam = Image.FromFile(file);
var cvImage = new Image<Bgr, byte>((Bitmap)exam);
processor = processorMain;
processor.ProcessImage(cvImage);
List<Point> newList = new List<Point>();
newList = processor.getList();
correct.correct(cvImage, answerKey, nOptions);
});
答案 0 :(得分:2)
实际问题/问题在评论中说明:
我每次迭代都是独立的,我不需要从一次迭代返回到另一次迭代。
在这种情况下,您不希望您的Image
是本地线程,您只需要本地。所以解决方案是简化:
Parallel.ForEach(ofd.FileNames,
(file) =>
{
var cvImage = new Image<Bgr, byte>((Bitmap)exam);
processor = processorMain;
processor.ProcessImage(cvImage);
List<Point> newList = new List<Point>();
newList = processor.getList();
correct.correct(newList, cvImage, answerKey, nOptions);
});
但是你的代码并没有在任何地方使用file
,所以这只是一个粗略的猜测。它还不正确。
另一方面,processorMain
,answerKey
和nOptions
的使用是潜在的问题。
经过多次评论后,您需要的是:
IList<Image> result = ofd.FileNames
.AsParallel()
.Select( (file) =>
{
Image exam = Image.FromFile(file);
...
return exam;
}).ToList();
答案 1 :(得分:0)
您的问题可能出在以下几行代码中:
processor = processorMain;
processor.ProcessImage(cvImage);
List<Point> newList = processor.getList(); // don't make a new list and then just throw it away by overwriting it.
看起来processor
正在处理您的图片并存储一些您稍后通过processor.getList()
调用访问的结果。但是如果多个线程并行运行,第二个线程可能会在第一个线程调用它之后但在第一个线程到达ProcessImage
之前调用processor.getList()
。这意味着第一个线程将从第二个线程获得列表结果。
最简单的解决方案是在每次迭代中创建一个处理器:
processor = new MyProcessorType();
processor.ProcessImage(cvImage);
List<Point> newList = new List<Point>();
newList = processor.getList();
这取决于处理器不依赖任何静态数据的假设。
另一种选择是修改处理器,使点列表存储在线程本地存储中。