简体   繁体   English

单独线程上的C#UI

[英]C# UI on separate thread

I keep seeing on various forums, tutorials or SO answers a recommendation to run the UI on a separate thread then the rest of the program to keep it responsive. 我经常在各种论坛,教程或SO上看到有关在独立线程上运行UI的建议,然后在程序的其余部分保持UI的响应速度。
How is this done in practice? 在实践中如何做到这一点? Does it mean editing program.cs to start a thread before loading the form? 这是否意味着在加载表单之前编辑program.cs以启动线程? Or does it mean that any non-trivial operation activated from within the form fork a thread and use that? 还是意味着从表单内部激活的任何非平凡操作都会派生线程并使用该线程? Or is it some setting? 还是有一些设置? How do you work with it?? 您如何使用它?

To keep UI responsive you should run other time consuming operations in a separate thread. 为了使UI保持响应,您应该在单独的线程中运行其他耗时的操作。 Usually user interface operations should be done in .NET's main (UI) thread. 通常,用户界面操作应在.NET的主(UI)线程中完成。

There are several ways to use a separate (background) thread for your operations. 有几种方法可以为操作使用单独的(后台)线程。 For Windows Forms applications, simplest option is BackgroundWorker component. 对于Windows窗体应用程序,最简单的选项是BackgroundWorker组件。

You can also create a Thread object yourself. 您也可以自己创建一个Thread对象。 But you should be careful about calling UI methods or changing UI controls properties in created thread. 但是,在调用UI方法或更改创建的线程中的UI控件属性时,应格外小心。 As I said, all the user interface operations (showing forms, changing controls texts or locations and so on) should be done in UI thread. 正如我所说,所有用户界面操作(显示表单,更改控件文本或位置等)都应该在UI线程中完成。 Otherwise you get an exception. 否则,您将获得例外。 To do that, you can use Control.Invoke method. 为此,可以使用Control.Invoke方法。

Typically in a C# WinForms application the Program.cs launches your main form like so. 通常,在C#WinForms应用程序中,Program.cs会这样启动您的主窗体。

Application.Run(new MyMainForm());

This creates your main dispatcher (GUI) thread where all of your events are fired on, (button click, form load etc) In practice, if you need to execute a long computation, you would create a new background worker thread and use that and the Invoke back to the event dispatcher when you were finished to update the UI. 这将创建触发所有事件的主调度程序(GUI)线程,(单击按钮,加载表单等)实际上,如果需要执行长时间的计算,则可以创建一个新的后台工作线程并使用该线程。完成更新UI后,调用回事件调度程序。

If you execute a long process on the UI thread it will lock the UI and it will become unresponsive. 如果您在UI线程上执行了很长的过程,它将锁定UI,并且将变得无响应。

The UI runs on the main thread. UI在主线程上运行。 The idea is to run lengthy operations in new threads. 这个想法是在新线程中运行冗长的操作。 Don't do every non-trivial operation in its own thread, but anything that causes the form to go "not responding" is a good candidate for a thread. 不要在自己的线程中执行每个非平凡的操作,但是任何导致表单“不响应”的事情都是线程的理想选择。

In C# it's probably easiest to use a BackgroundWorker instead of rolling your own threads. 在C#中,使用BackgroundWorker而不是滚动自己的线程可能是最简单的。

tutorials or SO answers a recommendation to run the UI on a separate thread ... I doubt that. 教程或SO回答了在单独线程上运行UI的建议 。我对此表示怀疑。 The UI runs on its own thread anyway. UI始终在自己的线程上运行。 Sometimes it's called the "main" thread of the application. 有时它被称为应用程序的“主”线程。 To avoid freezing your app, you do CPU intensive work in other threads. 为避免冻结应用程序,您需要在其他线程中进行CPU密集型工作。 The ways to do this are numerous. 做到这一点的方法很多。 Check out Thread, Task, Async, and and and. 检出线程,任务,异步和与和。 If you use Framework 4.5 you might use the await SomeTask feature, whenever it is POSSIBLE that the tasks needs more than 20-50 ms to complete - at least this is the recommandation from the MS guys (afaik) 如果您使用Framework 4.5,则可能会使用await SomeTask功能,只要任务有可能需要20-50毫秒以上的时间才能完成-至少这是MS专家的建议(afaik)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM