C#窗口在后台工作程序上形成一个带有函数的进度条

本文关键字:一个 函数 工作 后台 窗口 工作程序 程序上 | 更新日期: 2023-09-27 18:03:57

我正试图在我的c#excel加载项中添加一个进度条(MARQUEE样式(。进度条会出现,但在函数执行完毕之前不会显示任何进度,这意味着它保持冻结状态。

这些是Windows窗体类中的函数:

    public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            Thread.Sleep(100);
            //run in back thread
            backgroundWorker1.ReportProgress(i); 
        }
    }
    //call back method
    public void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    {
        progressBar1.Value = e.ProgressPercentage;
    }
    //call back method
    public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    {
        progressBar1.Value = progressBar1.Maximum;
    }

这就是我从加载项按钮调用函数的方式:

    private void buttonClicked(object sender, RibbonControlEventArgs e)
    {
        AddInPlanView.Form1 pBar = new AddInPlanView.Form1();
        pBar.Visible = true;
        pBar.backgroundWorker1.WorkerReportsProgress = true;
        pBar.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(pBar.backgroundWorker1_ProgressChanged);
        pBar.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(pBar.backgroundWorker1_DoWork);
        pBar.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(pBar.backgroundWorker1_RunWorkerCompleted);
        pBar.backgroundWorker1.RunWorkerAsync();
        FUNCTIONTORUN();
        pBar.Visible = false;
    }

我的代码现在尝试将进度条放在后台工作者上。我知道我应该切换这个,这样FUNCTIONTORUN()就应该是后台工作者,但我该怎么做呢?由于它是一个带字幕的进度条,我根本不需要更新进度条的值,它只需要运行到FUNCTIONTORUN()结束。请注意,FUNCTIONTORUN()会更新Excel工作表的单元格。

进度条是使用Visual Studio设计器初始化的。表单类中ProgressBar对象的名称为progressbar1

C#窗口在后台工作程序上形成一个带有函数的进度条

要启动字幕式进度条,请键入

progressbar1.Style = ProgressBarStyle.Marquee;
progressbar1.MarqueeAnimationSpeed = 100;

停止字幕型

progressbar1.MarqueeAnimationSpeed= 0;

来源:http://social.msdn.microsoft.com/forums/en-US/winforms/thread/9e51ad57-988e-4c17-98f0-cd2a8abec503/

FUNCTIONTORUN(); // make your UI thread busy. 
System.Windows.Forms.Application.DoEvents(); // might help in this case.

在大多数这种情况下,DoEvent没有帮助(根据我的经验(。所以,让流程条顺利工作是相当困难的。

当后台工作程序完成时,只需停止进度条。

在这个函数pBar.backgroundWorker1_RunWorkerCompleted中,只需调用进度条的Stop函数。

我认为您必须将FUNCTIONTORUN((放入sepratae线程中,并且它仍然是执行调用ReportProgress方法,以便在backgroundWorker1_ProgressChanged中更新您的进度条值。我想,因为我在提供的代码中没有看到它,所以您不会在代码中的某个地方调用ReportProgress函数。

编辑:看到ReportProgress函数。

因此,将函数移到单独的线程中,并将进度条的值更新到主线程中。

希望这能有所帮助。

谨致问候。

您的FUNCTIONTORUN()会阻塞UI线程
在长时间运行的函数中散布一些System.Windows.Forms.Application.DoEvents()来处理事件(这样UI就会更新(
如前所述,这将更新UI并让应用程序对其他事件做出响应
您可能希望禁用触发此长期运行函数或其他长期运行函数的按钮。

您可以创建一个额外的后台工作程序,其中包含对FUNCTIONTORUN((的调用的DoWork和一个使栏停止或不可见的RunWorkerCompleted。然后,不调用FUNCTIONTORUN((,而是调用backGroundWorker2.RunWorkerSync((;

这样可以防止该功能冻结您的UI。去年夏天,我在做几乎完全相同的事情时遇到了这个问题,并通过后台工作人员解决了这个问题。