[英]Windows Forms Parallel Drawing
Is it possible to draw on a panel using a Parallel.For
loop? 是否可以使用
Parallel.For
循环在面板上绘制? I have a multidimensional array of doubles, double[][] plants
, and I want to draw the columns in parallel, where each entry in the array is drawn as a rectangle in a grid on the panel. 我有一个由doubles,
double[][] plants
的多维数组,我想并行绘制列,其中数组中的每个条目都在面板上的网格中绘制为矩形。
On the line with grapahics.FillRectangle()
, I keep getting this error when I try: 在
grapahics.FillRectangle()
的行上,尝试进行时,我不断收到此错误:
An exception of type 'System.InvalidOperationException' occurred in System.Drawing.dll but was not handled in user code
System.Drawing.dll中发生类型为'System.InvalidOperationException'的异常,但未在用户代码中处理
Additional information: Object is currently in use elsewhere.
附加信息:当前在其他地方使用对象。
Here is the code I am using: 这是我正在使用的代码:
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();
});
I think what is happening is that the graphics object cannot handle multiple calls at once. 我认为正在发生的事情是图形对象无法一次处理多个调用。 Is there any way around this?
有没有办法解决? I tried creating a local reference to the graphics object in each parallel call but that did not work.
我尝试在每个并行调用中创建对图形对象的本地引用,但这没有用。
Is it possible to draw on a panel using a Parallel.For loop?
是否可以使用Parallel.For循环在面板上绘制?
No, not in any way that would actually be useful. 不,实际上没有任何用处。
UI objects, such as a Panel
, have "thread affinity". UI对象(例如
Panel
)具有“线程相似性”。 That is, they are owned by a particular thread, and must only ever be used in that thread. 也就是说,它们由特定线程拥有,并且只能在该线程中使用。
GDI+ objects, like your Graphics
object (you don't say where you got that object, but one hopes it was passed to you in PaintEventArgs
…if not, you have other design flaws in your code) can be more forgiving, but are not thread-safe. GDI +对象,例如您的
Graphics
对象(您不说在哪里得到该对象,但是希望它在PaintEventArgs
传递给您……如果没有,您的代码中还有其他设计缺陷)可能会更加宽容,但并非如此线程安全的。 You could add synchronization around the actual uses of the object, but those uses are the slow part. 您可以围绕对象的实际用途添加同步,但是这些用途是较慢的部分。 Serializing them will negate most of the benefit of concurrency in the code.
序列化它们将消除代码中并发的大部分好处。
Your question does not make clear whether your use of Parallel
here was even an actual attempt to address some specific performance problem, never mind what that problem actually was. 您的问题并不清楚您是否在此处使用
Parallel
甚至是解决某些特定性能问题的实际尝试,也不要介意该问题实际上是什么。 There are numerous questions with answers on Stack Overflow that discuss various techniques for improving rendering performance in Windows Forms code. 关于Stack Overflow的答案有很多问题,讨论了用于改善Windows Forms代码中呈现性能的各种技术。
In general, most of these techniques involve reducing the total amount of work done by caching as much as possible. 通常,大多数这些技术都涉及通过尽可能多地缓存来减少完成的工作总量。 Based on the code you've shown, there are at least two things you might want to do:
根据显示的代码,您可能至少要做两件事:
Parallel
, whenever the underlying parameters change. Parallel
进行计算的那部分。 Bitmap
object. Bitmap
对象中。 This will have to be done single-threaded, but a) it doesn't have to be done in the UI thread that owns your UI objects, and b) you (again) can do this just once, whenever the underlying parameters change. Bitmap
, then you can just draw the Bitmap
object when the Paint
event occurs, instead of having to re-render everything from scratch. Bitmap
之后,您就可以在Paint
事件发生时绘制Bitmap
对象,而不必从头开始重新渲染所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.