繁体   English   中英

c#如何使用BackgroundWorker的ProgressChanged事件在线程中间做UI动作

[英]c# how to use ProgressChanged event of BackgroundWorker to do UI actions in the middle of thread

这是一个简单的代码,它在后台工作人员的中间有 UI 操作。 上面有一个表格和一个标签“lbProgress”。 当 ProgressPercentage = 2 时,标签不会更改,但操作会更改。

    private void Form1_Load(object sender, EventArgs e)
    {
        bw.WorkerSupportsCancellation = true;
        bw.WorkerReportsProgress = true;
        bw.DoWork += bw_DoWork;
        bw.ProgressChanged += bw_ProgressChanged;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    }
    int ii;
    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        ii = 0;

        bw.ReportProgress(1);
        ii += 10;
        Thread.Sleep(1000);

        bw.ReportProgress(2); // here intended to do UI actions

        bw.ReportProgress(3);
        ii += 20;
        Thread.Sleep(1000);
    }
    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show(ii.ToString());
    }
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        lbProgress.Text = e.ProgressPercentage.ToString();
        if (e.ProgressPercentage == 2)
        {
            this.Text += ", 00";
            ii += 100;
            Thread.Sleep(1000);
        }
    }

    private void btRun_Click(object sender, EventArgs e)
    {
        bw.RunWorkerAsync();
    }

甚至可以使用 ProgressChanged 事件在后台工作线程中间执行大型 UI 操作吗?

这是我对您的问题“为什么我会看到这种行为?”的回答:

ReportProgress的文档中:

对 ReportProgress 方法的调用是异步的并立即返回。

所以会发生什么:

  • BackgroundWorker 调用 ReportProgress(2)
  • 进度 2 的 ProgressChanged 事件处理程序在 UI 线程和块上启动。 UI 未更新,因为 UI 线程被阻塞 (提示:通常只有在 UI 线程空闲时才会重绘屏幕)
  • 与此同时,BackgroundWorker 调用了 ReportProgress(3)
  • Blocked 事件处理程序终于完成
  • 进度 3 的 ProgressChanged 事件处理程序正在运行,将 lbProgress.Text 更新为“3”,然后您的眼睛有机会注意到它在一微秒前是“2”(如果它被渲染的话)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM