如何使用BackgroundWorker?

时间:2011-06-26 00:08:02

标签: c# backgroundworker

我知道它有3种方法。在我的程序中,我有一个发送消息的方法。这通常很晚,程序有时根本不响应按钮按下发送消息。有时它比我期望的晚5秒,程序冻结。我想使用BackgroundWorker按预期发送消息,并允许程序始终正常运行。我有用于在按钮处理程序中发送消息的代码。现在我在哪里放这个等效的代码?我希望所有这些仍然可以通过按钮按下来处理。

这是合适的处理程序吗?

backgroundWorker1.RunWorkerAsync();

并在:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {}

我要把我的代码放在按钮处理程序中? 而这之前:

carga.progressBar1.Minimum = 0;
carga.progressBar1.Maximum = 100;

Carga是ProgressBar的另一种形式。如何在此方案中使用BackgroundWorker?

2 个答案:

答案 0 :(得分:84)

您只能从ProgressChangedRunWorkerCompleted事件处理程序更新进度条,因为它们与UI线程同步。

基本理念是。 Thread.Sleep只是在这里模拟一些工作。将其替换为真实的路由呼叫。

public Form1()
{
    InitializeComponent();

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
    backgroundWorker1.WorkerReportsProgress = true;
}

private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

答案 1 :(得分:55)

我知道这有点旧,但是如果另一个初学者正在经历这个,我将分享一些代码,其中包含更多的基本操作,这是另一个示例,其中还包括取消该过程的选项并向用户报告该过程的状态。我将在上面的解决方案中添加Alex Aza给出的代码

public Form1()
{
    InitializeComponent();

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
    backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;  //Tell the user how the process went
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true; //Allow for the process to be cancelled
}

//Start Process
private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

//Cancel Process
private void button2_Click(object sender, EventArgs e)
{
    //Check if background worker is doing anything and send a cancellation if it is
    if (backgroundWorker1.IsBusy)
    {
        backgroundWorker1.CancelAsync();
    }

}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);

        //Check if there is a request to cancel the process
        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            backgroundWorker1.ReportProgress(0);
            return;
        }
    }
    //If the process exits the loop, ensure that progress is set to 100%
    //Remember in the loop we set i < 100 so in theory the process will complete at 99%
    backgroundWorker1.ReportProgress(100);
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
         lblStatus.Text = "Process was cancelled";
    }
    else if (e.Error != null)
    {
         lblStatus.Text = "There was an error running the process. The thread aborted";
    }
    else
    {
       lblStatus.Text = "Process was completed";
    }
}