BackgroundWorker не запускает RunWorkerCompleted - PullRequest
1 голос
/ 03 октября 2011

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

Если я запустлю его снова, сетка данных очищается и не обновляется.Я не могу понять, почему.

Я убедился, что таблица данных содержит строки, когда мой код обращается к dgvReadWrites.DataSource.

    private void btnGenerateStats_Click(object sender, EventArgs e)
    {
        dtJobReadWrite.Columns.Clear();
        dtJobReadWrite.Rows.Clear();
        dgvReadWrites.DataSource = dtJobReadWrite;

        List<Tuple<string, string>>jobs = new List<Tuple<string, string>>();

        foreach (ListViewItem job in lstJobs.SelectedItems)
        {
            jobs.Add(new Tuple<string, string>(job.Text, job.SubItems[2].Text));
        }
        BackgroundWorker bgw = new BackgroundWorker();
        bgw.WorkerReportsProgress = true;
        bgw.WorkerSupportsCancellation = true;
        bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
        bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
        pbarGenStats.Style = ProgressBarStyle.Marquee;
        pbarGenStats.MarqueeAnimationSpeed = 30;
        pbarGenStats.Visible = true;
        bgw.RunWorkerAsync(jobs);
    }


    private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bgw = sender as BackgroundWorker;
        List<Tuple<string, string>> jobs = (List<Tuple<string, string>>)e.Argument;
        GetReadWriteStats(jobs);
    }

    private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        BackgroundWorker bgw = sender as BackgroundWorker;
        bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
        bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork);
        pbarGenStats.MarqueeAnimationSpeed = 0;
        pbarGenStats.Value = 0;
        pbarGenStats.Visible = false;
        dgvReadWrites.DataSource = dtJobReadWrite;
        dgvReadWrites.Visible = true;
        dgvReadWrites.Refresh();
    } 

Ответы [ 3 ]

3 голосов
/ 03 октября 2011
private void btnGenerateStats_Click(object sender, EventArgs e)
{
    //...
    dgvReadWrites.DataSource = dtJobReadWrite;
    // etc...
}

Это проблема, вы обновляете dtJobReadWrite в BGW. Это приводит к тому, что связанная сетка обновляется рабочим потоком. Недопустимо, элементы управления не являются потокобезопасными и могут обновляться только из потока, который их создал. Обычно это проверяется, создавая InvalidOperationException во время отладки, но эта проверка не работает для связанных элементов управления.

Что происходит дальше, повсюду, вам повезло, что вы получили очень повторяемый тупик. Более распространенное неправильное поведение - случайные рисования артефактов и тупик, только когда вы не находитесь рядом. Исправлено:

    dgvReadWrites.DataSource = null;

и повторное связывание сетки в обработчике событий RunWorkerCompleted, как вы уже делаете.

0 голосов
/ 03 октября 2011

Почему вы создаете новый BackgroundWorker каждый раз, когда хотите его запустить?Я хотел бы посмотреть, что происходит с этим кодом, если вы используете один экземпляр BackgroundWorker (GetReadWriteWorker или что-то в этом духе), подписываетесь на события только один раз, а затем запускаете этот рабочий Async на btnGenerateStats_Click.

0 голосов
/ 03 октября 2011

Поскольку вы отписываетесь от этих событий

bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
bgw.DoWork -= new DoWorkEventHandler(bgw_DoWork);

Удалите эти строки

...