如何正确地在WinForms中创建多线程GUI应用程序?

12 浏览
0 Comments

如何正确地在WinForms中创建多线程GUI应用程序?

我来自C背景,目前我想制作一个具有响应式GUI和长时间运行的工作线程的小型WinForms实用工具。

GUI是常规的Form1派生类,具有进度指示器等功能,工作线程是new System.Threading.Thread();这种类型。

在C++中,一切都很简单,在.NET中,我不知道该怎么做。

有没有一种类似于PostMessage的方法来更新数据?我应该在主线程上启动一个定时器来读取受共享锁保护的结构,还是有其他方法?我看过多个关于委托的文档,但在阅读了10篇不同的文章后,它们似乎并不起作用,也许是因为我有一个工作线程<->GUI的关系,而不是GUI<->GUI的关系。

所有GUI相关的内容都在GUI类中,所有工作线程相关的内容都在它自己的工作线程类中。在托管世界中,最佳实践是什么?

0
0 Comments

在WinForms中正确地创建线程化的GUI应用程序是一个常见的问题。有多种方法可以解决这个问题,但简单来说,可以采取以下步骤:

1. 启动一个线程。

2. 使用InvokeRequired和Invoke()方法返回到GUI线程。

另外,BackgroundWorker类提供了一种更简单的方法。

如果我理解正确的话,在这种情况下,数据处理库拥有GUI,它会不时地更新GUI。我所寻找的是GUI<->[进度存储]<->逻辑和数据层之间的通信。GUI启动数据处理,但会定期检查事件,以查看是否有新的进度存储数据可用,并根据需要更新GUI元素。这种情况是否可行?

然后启动一个新线程,使用一个可以被GUI直接访问的共享对象(这样GUI可以插入内容)和新线程。如果需要,可以发出信号通知线程有更新,线程会处理新的更新并调用Control.Invoke()方法来更新GUI。

是的,这就是我寻找的,但是如果.NET中没有PostMessage架构,我如何通知GUI?

你只需要使用Control.Invoke(YourFunction)这一行代码,其他的PostMessage等操作都在后台自动完成。

我尝试将Form1的引用传递给工作线程,然后调用MethodInvoker action = delegate { Form1.UpdateGUI(); }; Form1.BeginInvoke(action);。但仍然会出现从错误线程调用的异常。

找到了解决方法:stackoverflow.com/questions/519233/…

0
0 Comments

这个问题的出现原因是在WinForms应用程序的程序类中只有一个单线程。解决方法有两种:一种是将[STAThread]替换为[MTAThread],这样可以处理多个线程;另一种是在运行时使用System.Threading创建线程。但是,由于工作线程是通过按钮点击创建的,所以它们要么被调度到线程池中,要么通过Form1交互时启动线程。因此,我仍然需要在[STAThread]中,对吗?顺便说一句,STA/MTA是COM的内容,对吗?所以基本上,由于这是一个GUI应用程序,无论如何GUI线程(运行Main并稍后进行Form1泵)都必须是STA线程。

0
0 Comments

在WinForms中正确创建线程化的GUI应用程序?

在WinForms中,我们想要创建一个具有线程化功能的GUI应用程序。但是,我们需要知道在使用WinForms时,应该使用哪种方法来实现线程化的GUI应用程序。

以下是一些常见的方法:

1. 使用BackgroundWorker:使用BackgroundWorker类可以在后台线程上执行操作,并在完成后更新GUI。它提供了方便的事件和方法来处理进度报告和取消操作。

2. 使用Control.Invoke:Control.Invoke方法允许在GUI线程上执行操作。这在需要在后台线程中执行操作并更新GUI时非常有用。

3. 使用SynchonizationContext:SynchonizationContext类提供了一种在指定线程上执行操作的方法。它可以用来执行GUI操作并确保线程安全。

4. 使用Task Parallel Library(System.Threading.Tasks):Task Parallel Library(TPL)提供了一种简化并行编程的方法。它可以与WinForms一起使用,以实现线程化的GUI应用程序。

5. 使用Rx:Rx(Reactive Extensions)是一种用于编写异步和事件驱动程序的库。它提供了一种简化处理异步操作的方法,并可以与WinForms一起使用。

6. 不要使用Thread.Start或ThreadPool:在WinForms中,不推荐直接使用Thread.Start或ThreadPool来创建线程。这是因为这种方法过于低级,可能会导致线程安全和其他问题。

以上是一些常见的方法来创建线程化的GUI应用程序。根据个人的需求和偏好,选择合适的方法来实现线程化的GUI应用程序。

0