在应用程序执行长时间运行的任务时,您是否有一个很好的解决方案来保持“请等待”winform“绘制”?
我尝试在每一步使用form.refresh(),但是有一些长时间运行的查询,这意味着这不够频繁。
基本上是这个SO Question但是,通过VSTO(而不是Python)在Excel中的C#上。
答案 0 :(得分:3)
正如statichippo所提到的,我会使用BackgroundWorker类。其目的是简化多线程并允许工作线程在不锁定GUI的情况下进行耗时的处理。
以下是MSDN的引用:
BackgroundWorker类允许您 在一个单独的, 专用线程。耗时的 下载和数据库等操作 交易可能会导致您的用户 界面(UI)看起来好像它 他们已经停止了回应 运行。当您需要响应式UI时 你面临着长时间的拖延 与此类操作相关联的 BackgroundWorker类提供了一个 方便的解决方案。
这是一个很好的教程,如何在Windows窗体中使用BackgroundWorker类:Implementing multi-threading in WinForms using the BackgroundWorker class
对于复杂场景,有更复杂的方法在C#中实现多线程,但对于大多数简单场景,BackgroundWorker工作得很好(至少对我来说)。
以下是我在C#Multi Threading上从Google上提取的一些链接:
MSDN Threading
Introduction to Multithreading in C#
答案 1 :(得分:1)
另一种选择是使用异步委托在线程池线程上显示表单。
对于在整个应用程序持续时间内不能持续的较短生存线程,建议使用线程池中的线程。由于这是显示一个短暂的请等待窗口,因此线程池是一个合理的选择。
Action委托(.NET 2.0+)与它的BeginInvoke()方法一起使用,以在线程池线程上自动运行委托代码。
一些注意事项:
m_pleaseWaitForm.ShowDialog();
实际上在新线程中启动了一个新的消息循环。这就是让请等待表格保持活力的原因。 (MethodInvoker)delegate { ... }
只是一种在委托内联中运行代码的.NET 2.0方式。 下面的示例可以添加到包含Form1的WinForms项目:主窗体,Form2:请等待表单。
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(); });
}
答案 2 :(得分:0)
使用BackgroundWorker
答案 3 :(得分:0)
专门用于启动画面,但是创建一个请等待窗口几乎是相同的过程(可能减去一些浮华的不透明度)。
关键信息是您需要一个单独的线程。这可能会使事情变得复杂,但文章提供了一个很好的覆盖/示例,说明如何正确地做到这一点。