C# 长时间运行任务的Winform更新

C# 长时间运行任务的Winform更新,c#,winforms,vsto,long-running-processes,C#,Winforms,Vsto,Long Running Processes,当应用程序执行长时间运行的任务时,您是否有一个好的解决方案来保持“请等待”winform“绘制” 我已经尝试在每个步骤中使用form.refresh(),但是出现了一些长时间运行的查询,这意味着这不够频繁 基本上是这样的,但是在C上,通过VSTO(而不是Python)在Excel中使用C#时,请使用BackgroundWorker,并使用C#中的代码 这是专门为闪屏设计的,但创建“请等待”窗口的过程几乎相同(可能会减去一些浮华的不透明度) 关键信息是,您将需要一个单独的线程。这可能会使事情复杂化

当应用程序执行长时间运行的任务时,您是否有一个好的解决方案来保持“请等待”winform“绘制”

我已经尝试在每个步骤中使用form.refresh(),但是出现了一些长时间运行的查询,这意味着这不够频繁


基本上是这样的,但是在C上,通过VSTO(而不是Python)在Excel中使用C#时,请使用BackgroundWorker,并使用C#中的代码

这是专门为闪屏设计的,但创建“请等待”窗口的过程几乎相同(可能会减去一些浮华的不透明度)


关键信息是,您将需要一个单独的线程。这可能会使事情复杂化,但是本文给出了一个很好的介绍/示例,说明如何正确地执行此操作。

另一个选项是使用异步委托在线程池线程上显示表单

建议线程池中的线程用于寿命较短且不会持续整个应用程序持续时间的线程。因为这是为了显示一个短暂的请等待窗口,所以线程池是一个合理的选择

操作委托(.NET 2.0+)与其BeginInvoke()方法一起用于在线程池线程上自动运行委托代码

一些注意事项:

  • 对于任何跨线程GUI调用,如在ClosePleaseWait()中关闭please wait表单,使用Control.BeginInvoke非常重要
  • 另外,
    m_请访问itform.ShowDialog()实际上在新线程中启动一个新的消息循环。这是保持“请等待”窗体活动的原因
    
  • 因为使用了线程池线程,所以该线程自动成为后台线程,并且在主应用程序关闭时将终止
  • 除了在另一个线程上运行外,Form2没有什么特别之处。您可以在其上放置任何子控件,如图片框、标签等
  • (MethodInvoker)委托{…}
    只是一种.NET 2.0方式,用于在委托内联中运行代码
下面的示例可以添加到包含Form1:main表单和Form2:please wait表单的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(); });
    }
private Form2 m_plesewaitform=null;
显示私有void Form1_(对象发送方,事件参数e)
{
//该代码也可以放在一个按钮点击事件处理程序中。
动作a=新动作(ShowPleaseWait);
a、 BeginInvoke(this.Bounds,null,null);
//做你的长时间跑步任务
关闭它();
}
私有void显示(矩形边界)
{
//此方法在新线程上运行。
m_pleaseWaitForm=新表格2();
m_pleaseWaitForm.TopMost=真;
m_pleaseWaitForm.Location=新点(bounds.Left+bounds.Width/2-m_pleaseWaitForm.Width/2,bounds.Top+bounds.Height/2-m_pleaseWaitForm.Height/2);
m_pleaseWaitForm.ShowDialog();
}
私人作废关闭
{
m_pleaseWaitForm.BeginInvoke((MethodInvoker)委托{m_pleaseWaitForm.Close();});
}

正如statichippo提到的,我将使用BackgroundWorker类。它的目的是简化多线程,并允许工作线程在不锁定GUI的情况下执行耗时的处理

以下是一段引自:

BackgroundWorker类允许您 要在单独的服务器上运行操作, 专用线程。费时的 下载和数据库等操作 事务可能会导致您的用户 界面(UI)看起来好像 已停止响应 跑步当你想要一个响应性强的用户界面时 你面临着长时间的拖延 与此类操作相关联的 BackgroundWorker类提供了 方便的解决方案

以下是如何在windows窗体中使用BackgroundWorker类的良好教程:

在C#中有更复杂的方法来实现多线程,对于复杂的场景,但是对于大多数简单的场景,BackgroundWorker工作得很好(至少对我来说)

以下是我从谷歌上获得的一些关于C#多线程的链接:


老兄,我累了——我还以为这是winforms。答案应该是使用AJAX(MS-AJAX可以很好地工作)。您可以使用计时器控件来检查状态。然后您可以在完成时重定向。很抱歉投票失败,问题已从webforms=>winforms更改。我相信statichippo是正确的。使用backgroundworker线程应该可以为您做到这一点。这是真正的web表单,还是winforms?您正在谈论Excel和VSTO。如果是webforms,您没有刷新方法。对不起,是的,Winforms,不是webforms。。编辑了这个问题。。。这是漫长的一天…有完整源代码示例的最终解决方案吗?使用长时间运行的流程和使用C#,signer的步骤如何?谢谢您的链接。工作非常好,并集成到我的Excel VSTO应用程序中非常好!