簡體   English   中英

為什么主線程在后台工作程序執行時被掛起

[英]Why main thread gets hanged when background worker is executing

我有簡單的winforms應用程序,我有按鈕。 點擊按鈕我正在做這樣的事情

    private void Button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw_Convert = new BackgroundWorker();
        bw_Convert.WorkerReportsProgress = true;
        bw_Convert.DoWork += bw_Convert_DoWork;
        bw_Convert.RunWorkerCompleted += bw_Convert_RunWorkerCompleted;
        bw_Convert.ProgressChanged += bw_Convert_ProgressChanged;
        bw_Convert.WorkerReportsProgress = true;
        bw_Convert.RunWorkerAsync();
    }

我有以下代碼為后台工作者

   public void bw_Convert_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i <= 1000000; i++)
        {                
            bw_Convert.ReportProgress((100 * (i) / 1000));
        }
    }
    public void bw_Convert_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {           

        progressBarControl1.EditValue = e.ProgressPercentage.ToString();
    }

通過做這個。 為什么我的主線程被掛起,因為我正在處理Background Worker中的東西。

因為ReportProgress事件處理程序在主線程上執行:

對ReportProgress方法的調用是異步的,並立即返回。 ProgressChanged事件處理程序在創建BackgroundWorker的線程上執行。

因此,您不斷從后台線程調用ReportProgress ,它使您的主線程不斷忙於處理此事件。

如果您在后台有很多快速工作要做,那么嘗試僅報告每次第n次迭代,而不是在每次迭代時引發事件:

public void bw_Convert_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 1000000; i++)
    {   
        if (i % 10000 == 0)
           bw_Convert.ReportProgress(i);
        // do something
    }
}

ProgressChanged事件在UI線程上執行,因此您可以訪問控件。
后台工作程序中的代碼在很短的時間內執行,導致在很短的時間內引發許多事件,使代碼作出反應,好像它將在UI線程上完全執行。

事實上,大部分的工作在UI線程中完成的,因為更新屏幕上的控制比循環迭代更多的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM