【发布时间】:2012-11-06 11:57:23
【问题描述】:
我一直在各种论坛、教程或 SO 上看到一个建议,即在单独的线程上运行 UI,然后在程序的其余部分上运行以保持响应。
这在实践中是如何做到的?这是否意味着在加载表单之前编辑program.cs 以启动线程?或者这是否意味着从表单中激活的任何重要操作都会派生一个线程并使用它?还是有什么设定?你是如何使用它的??
【问题讨论】:
标签: c# multithreading user-interface
我一直在各种论坛、教程或 SO 上看到一个建议,即在单独的线程上运行 UI,然后在程序的其余部分上运行以保持响应。
这在实践中是如何做到的?这是否意味着在加载表单之前编辑program.cs 以启动线程?或者这是否意味着从表单中激活的任何重要操作都会派生一个线程并使用它?还是有什么设定?你是如何使用它的??
【问题讨论】:
标签: c# multithreading user-interface
通常在 C# WinForms 应用程序中,Program.cs 会像这样启动您的主窗体。
Application.Run(new MyMainForm());
这会创建您的主调度程序 (GUI) 线程,您的所有事件都会在其中触发,(按钮单击、表单加载等)实际上,如果您需要执行长时间的计算,您将创建一个新的后台工作线程并完成更新 UI 后,使用它并调用返回给事件调度程序。
如果您在 UI 线程上执行较长的进程,它将锁定 UI 并变得无响应。
【讨论】:
UI 在主线程上运行。这个想法是在新线程中运行冗长的操作。不要在自己的线程中执行所有重要的操作,但是任何导致表单“不响应”的操作都是线程的良好候选者。
在 C# 中,使用 BackgroundWorker 而不是滚动您自己的线程可能是最简单的。
【讨论】:
为了保持 UI 响应,您应该在单独的线程中运行其他耗时的操作。通常用户界面操作应该在 .NET 的主 (UI) 线程中完成。
有几种方法可以为您的操作使用单独的(后台)线程。对于 Windows 窗体应用程序,最简单的选项是BackgroundWorker 组件。
您也可以自己创建一个Thread 对象。但是您应该小心调用 UI 方法或更改创建线程中的 UI 控件属性。正如我所说,所有用户界面操作(显示表单、更改控件文本或位置等)都应该在 UI 线程中完成。否则你会得到一个例外。为此,您可以使用Control.Invoke 方法。
【讨论】:
tutorials or SO 回答了在单独线程上运行 UI 的建议 ...我对此表示怀疑。无论如何,UI 都在自己的线程上运行。有时它被称为应用程序的“主”线程。为了避免冻结您的应用程序,您在其他线程中执行 CPU 密集型工作。做到这一点的方法很多。查看线程、任务、异步和和和。
如果您使用 Framework 4.5,您可能会使用 await SomeTask 功能,只要任务可能需要超过 20-50 毫秒才能完成 - 至少这是 MS 家伙 (afaik) 的建议
【讨论】: