是否可以创建可以从两个线程访问的GUI控件?

时间:2015-07-14 14:33:51

标签: c# multithreading winforms

为了从头创建一个小2D游戏,我想在WinForm上创建一个面板并使用Graphics-object绘制它(顺便说一下,我是否必须使用面板或者我可以只绘制到直接形式?我知道你可以做到这一点,但缺点在哪里?)。

现在我想在不同的线程中连续运行两个循环。应该主要分配一个线程来进行计算,而另一个线程应该主要绘制到面板。但是,在某些情况下,两个线程都应该能够绘制到面板,这就是我的问题。如您所知,如果您尝试简单地访问不是为该特定线程创建的GUI控件,则会发生错误。我也不想总是使用像

这样的代码
if (control1.InvokeRequired)
{
control1.Invoke(new MethodInvoker(delegate { control1.Text = string1; }));
}

因为我真的不熟悉这个选项。有没有办法以某种方式创建我的面板,以便两个线程都可以轻松访问它或者这是不可能的?

1 个答案:

答案 0 :(得分:4)

  

有没有办法以某种方式创建我的面板,以便两个线程都可以轻松访问它或者这是不可能的?

没有。你不想那样做。在Windows中有很多历史背后的原因,但简短的回答是,GUI线程应该完成所有绘图并访问所有控件。

  顺便说一句,我是否必须使用面板或者我可以直接绘制到表单?我知道你可以做到这一点,但缺点在哪里?

WinForms通常不是高性能绘图的最佳选择 - 它完全由CPU而不是GPU绘制。您可以将WPF用于某些硬件辅助绘图,但通常的方法是使用DirectX方法并使用DirectDraw或Direct2D之类的东西。但是,根据您的期望和需求,WinForms可能会正常工作。

要回答您的实际问题,直接在表单本身与Panel上绘图之间没有太大区别。

  

因为我真的不熟悉这个选项。

我喜欢CodeCaster对此的评论。花一点时间在它上面,它应该不会太困难。 “GUI线程”(主线程,无论您想要调用它)都在消息泵上运行。将其视为具有不同优先级的队列。 GUI线程只是将时间花在处理队列中的项目的消息循环中。 “将此控件的文本设置为”,“在此处绘制”,“重新绘制,因为窗口已调整大小”等等。Control.Invoke归结为在GUI队列中添加项目以供GUI线程执行。