[英]Windows Forms Parallel Drawing
是否可以使用Parallel.For
循环在面板上绘制? 我有一个由doubles, double[][] plants
的多维数组,我想并行绘制列,其中数组中的每个条目都在面板上的网格中绘制为矩形。
在grapahics.FillRectangle()
的行上,尝试进行时,我不断收到此错误:
System.Drawing.dll中发生类型为'System.InvalidOperationException'的异常,但未在用户代码中处理
附加信息:当前在其他地方使用对象。
这是我正在使用的代码:
Parallel.For(0, simWidth, i =>
{
Color plantColor;
RectangleF plantRectangle= new Rectangle();
SolidBrush plantBrush = new SolidBrush(Color.Black);
for (int j = 0; j < simHeight; ++j)
{
int r, g = 255, b;
r = b = (int)(255 * (Math.Tanh(simulation.plants[i, j]) + 1) / 2.0);
plantColor = Color.FromArgb(100, r, g, b);
plantBrush.Color = plantColor;
plantRectangle.Location = new PointF(i * cellSize, j * cellSize);
graphics.FillRectangle(plantBrush, plantRectangle);
}
plantBrush.Dispose();
});
我认为正在发生的事情是图形对象无法一次处理多个调用。 有没有办法解决? 我尝试在每个并行调用中创建对图形对象的本地引用,但这没有用。
是否可以使用Parallel.For循环在面板上绘制?
不,实际上没有任何用处。
UI对象(例如Panel
)具有“线程相似性”。 也就是说,它们由特定线程拥有,并且只能在该线程中使用。
GDI +对象,例如您的Graphics
对象(您不说在哪里得到该对象,但是希望它在PaintEventArgs
传递给您……如果没有,您的代码中还有其他设计缺陷)可能会更加宽容,但并非如此线程安全的。 您可以围绕对象的实际用途添加同步,但是这些用途是较慢的部分。 序列化它们将消除代码中并发的大部分好处。
您的问题并不清楚您是否在此处使用Parallel
甚至是解决某些特定性能问题的实际尝试,也不要介意该问题实际上是什么。 关于Stack Overflow的答案有很多问题,讨论了用于改善Windows Forms代码中呈现性能的各种技术。
通常,大多数这些技术都涉及通过尽可能多地缓存来减少完成的工作总量。 根据显示的代码,您可能至少要做两件事:
Parallel
进行计算的那部分。 Bitmap
对象中。 这必须是单线程完成的,但是a)不必在拥有UI对象的UI线程中完成,并且b)只要基础参数发生更改,您(再次)只能执行一次。 绘制成Bitmap
之后,您就可以在Paint
事件发生时绘制Bitmap
对象,而不必从头开始重新渲染所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.