c # backgroundWorker не вызывает события ProgressChanged или RunWorkerCompleted - PullRequest
5 голосов
/ 24 мая 2011

Использование C # .NET 3.5.

Кажется, я не единственный, так как поиск, по-видимому, поднимает много похожих вопросов, однако, читая их, я все еще не нашел решения.

Я вызываю событие нажатием кнопки на моем пользовательском интерфейсе, который затем должен запускать backgroundWorker для выполнения некоторой трудоемкой работы - в этом случае я хочу, чтобы он собирал информацию из формы и а) записывал в XML-файл, а также б) вставить информацию в удаленную базу данных.

Это именно то, для чего backgroundWorker был разработан и предназначен для этого, я верю.

Вот код события.

private void btnFinish_Click(object sender, EventArgs e)
{
    clkFinish.setInstant();
    curAct.setTimeFinish(DateTime.Now);
    btnStart.Enabled = true;
    bgwDataWorker.RunWorkerAsync();
    for (int i = 0; i < 20; i++)
    {
        Console.WriteLine("Thread a: " + i);
        Thread.Sleep(100);
        if (i == (20 - 1))
        {
            Console.WriteLine("Finished");
        }
    }

}

Как видите, у меня есть некоторый код, который я использовал в качестве противовеса фоновому рабочему коду, который здесь:

private void bgwDataWorker_DoWork(object sender, DoWorkEventArgs e)
{
    Console.WriteLine("Running in a different thread now");
    int count = 0;
    for (int i = 0; i < 21; i++)
    {
        Console.WriteLine("Thread b: " + i);
        Thread.Sleep(100);
        (sender as BackgroundWorker).ReportProgress(5 * i, null);
        if (i == (21 - 1))
        {
            count = i;
        }
    }
    e.Result = count;
}

Пока что, кажется, все работает до этого момента.

Моя проблема в том, что когда код в методе DoWork завершается, ничего не происходит. Вот методы ProgressChanged и RunWorkerComplete.

private void bgwDataWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Console.WriteLine(e.ProgressPercentage);
}

private void bgwDataWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    Console.WriteLine("Result is " + e.Result.ToString());

}

Это меня озадачило.

Я попытался запустить примеры из MSDN , и у меня возникли те же проблемы. События RunWorkerCompleted и ReportProgress по какой-то причине просто не генерируются, и я не понимаю, почему.

Спасибо за чтение.

Alan

Ответы [ 7 ]

5 голосов
/ 16 июня 2011

У меня была такая же проблема, и я только разобрался с ответом.

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

5 голосов
/ 24 мая 2011

Вы не пропустили установку этих переменных, не так ли?

backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;

Также это может быть исключением в методе DoWork, который не обрабатывается.

3 голосов
/ 17 июня 2011

Inksmithy, вы упомянули, что переименовали BackgroundWorker. Обратите внимание, что при этом конструктор форм НЕ автоматически изменяет ссылку на старые методы DoWork и RunWorkerCompleted. Поэтому в конструкторе форм щелкните свой BackgroundWorker, затем щелкните значок «События» (молния) в окне свойств и дважды проверьте, что он указывает на правильные имена методов событий.

1 голос
/ 24 мая 2011

Установите для свойства WorkerReportsProgress значение True.

0 голосов
/ 21 мая 2014

У меня недавно была эта проблема.Это было вызвано тем, что основной поток спал до тех пор, пока не завершился фоновый поток, что заблокировало выполнение обновления.

Я решил эту проблему, поместив свой объект (содержащий рабочие потоки) в другой поток, чтобы обновление прогресса моглоВыполните, измените значения в главном потоке, чтобы продолжить работу моего спящего потока.

0 голосов
/ 28 октября 2012

У меня был один проект [A], (построенный некоторое время назад), у которого работал индикатор выполнения.Текущее приложение [B] не сообщает о прогрессе.По какой-то причине приложение [A] было настроено на обработчики событий.Итак, я подключил обработчики событий в app [B], и это работает.Обработчики копируются в файл частичного класса designer.cs.(Предполагая, что они могут быть в частичном классе form.cs).

// 
        // backgroundWorker1
        // 
        this.backgroundWorker1.WorkerReportsProgress = true;
        this.backgroundWorker1.WorkerSupportsCancellation = true;
        this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
        this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
        this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
//

надеюсь, это поможет.Не знаю, почему приложение [A] было подключено с помощью панели инструментов для удаления фонового рабочего окна в окне дизайна формы.Использование VS2012 и Windows 7.

Кроме того, я рассчитываю процент выполнения и по какой-то причине количество элементов в списке, умноженное на количество выбранных флажков, превысило 100% - оно выкинуло и выдает ошибку.Таким образом, я ограничу процент до 99 и включу эту часть моей логики в то, что процент прогресса сообщается на мероприятии.

0 голосов
/ 24 мая 2011

Вы пропустили важный бит - логический флаг, позволяющий ему вызывать события

bgwDataWorker.WorkerReportsProgress = true;
bgwDataWorker.WorkerSupportsCancellation = true;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...