当应用程序执行长时间运行的任务时,您是否有一个很好的解决方案来保持“请稍候”winform“绘制”?
我已经尝试在每个步骤中使用 form.refresh() ,但是会发生一些长时间运行的查询,这意味着这不够频繁。
基本上这个SO Question但是,通过 VSTO(而不是 Python)在 Excel 中的 C# 上。
当应用程序执行长时间运行的任务时,您是否有一个很好的解决方案来保持“请稍候”winform“绘制”?
我已经尝试在每个步骤中使用 form.refresh() ,但是会发生一些长时间运行的查询,这意味着这不够频繁。
基本上这个SO Question但是,通过 VSTO(而不是 Python)在 Excel 中的 C# 上。
正如 statichippo 提到的,我会使用 BackgroundWorker 类。其目的是简化多线程并允许工作线程在不锁定 GUI 的情况下进行耗时的处理。
这是来自MSDN的引用:
BackgroundWorker 类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时的操作可能会导致您的用户界面 (UI) 在运行时似乎停止响应。当您需要响应式 UI 并且面临与此类操作相关的长时间延迟时,BackgroundWorker 类提供了一种方便的解决方案。
这是一个很好的教程,如何在 Windows 窗体中使用 BackgroundWorker 类: 使用 BackgroundWorker 类在 WinForms 中实现多线程
对于复杂的场景,在 C# 中实现多线程有更复杂的方法,但对于大多数简单的场景,BackgroundWorker 工作得很好(至少对我来说)。
以下是我从 Google 获取的关于 C# 多线程的一些链接:
MSDN Threading
Introduction to Multithreading in C#
另一种选择是使用异步委托在线程池线程上显示表单。
建议将线程池中的线程用于不会持续整个应用程序持续时间的较短生命周期的线程。由于这是显示一个短暂的请等待窗口,线程池是一个合理的选择。
Action 委托 (.NET 2.0+) 与 BeginInvoke() 方法一起用于在线程池线程上自动运行委托代码。
一些注意事项:
m_pleaseWaitForm.ShowDialog();
实际上在新线程中启动了一个新的消息循环。这就是请等待表单保持活力的原因。 (MethodInvoker)delegate { ... }
只是在委托内联中运行代码的 .NET 2.0 方式。下面的示例可以添加到包含 Form1:主窗体和 Form2:请等待窗体的 WinForms 项目中。
private Form2 m_pleaseWaitForm = null;
private void Form1_Shown(object sender, EventArgs e)
{
// This code could also be placed in eg. a button click event handler.
Action<Rectangle> a = new Action<Rectangle>(ShowPleaseWait);
a.BeginInvoke(this.Bounds, null, null);
// Do your long running tasks
ClosePleaseWait();
}
private void ShowPleaseWait(Rectangle bounds)
{
// This method runs on the new thread.
m_pleaseWaitForm = new Form2();
m_pleaseWaitForm.TopMost = true;
m_pleaseWaitForm.Location = new Point(bounds.Left + bounds.Width / 2 - m_pleaseWaitForm.Width / 2, bounds.Top + bounds.Height / 2 - m_pleaseWaitForm.Height / 2);
m_pleaseWaitForm.ShowDialog();
}
private void ClosePleaseWait()
{
m_pleaseWaitForm.BeginInvoke((MethodInvoker)delegate { m_pleaseWaitForm.Close(); });
}
使用 BackgroundWorker
这是一个很好的 C# 代码示例。
它专门用于启动屏幕,但是创建“请稍候”窗口的过程几乎相同(可能减去了一些华丽的不透明度)。
关键信息是您将需要一个单独的线程。这可能会使事情复杂化,但是本文提供了一个很好的覆盖范围/示例,说明了如何正确地做到这一点。