Как использовать BackgroundWorker? - PullRequest
58 голосов
/ 26 июня 2011

Я знаю, что есть 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 ]

85 голосов
/ 26 июня 2011

Вы можете обновить индикатор выполнения только из ProgressChanged или RunWorkerCompleted обработчиков событий, поскольку они синхронизируются с потоком пользовательского интерфейса.

Основная идея такова.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;
}
56 голосов
/ 10 июня 2015

Я знаю, что это немного устарело, но в случае, если другой новичок проходит через это, я поделюсь некоторым кодом, который охватывает немного больше основных операций, вот еще один пример, который также включает в себя возможность отменить процесса также сообщать пользователю о состоянии процесса.Я собираюсь добавить поверх кода, данного Алекса Аза в решении выше

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";
    }
}
...