簡體   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