как использовать фоновый рабочий в WPF C # в коммутаторе

#c# #wpf #switch-statement #backgroundworker

#c# #wpf #switch-statement #фоновый рабочий

Вопрос:

Как я могу использовать фоновый рабочий несколько раз с разными Dowork по одному за раз после перехода от одного процесса к другому процессу?

У меня есть этот код:

 foreach (string item in Processes)
{
    ItemValue = item;
    //Get process code for the process under the selected source
    GetActiveProcess();

    switch (ProcessCode)
    {
        case "Download File":
            GetStartTime();
            UpdateDownloadStartTime();

            if (worker.IsBusy != true)
            {
                worker.DoWork  = new DoWorkEventHandler(worker_DoWorkDownload);
                worker.RunWorkerCompleted  = new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                worker.RunWorkerAsync();
            }
            break;

        case "Unzip File":
            GetStartTime();
            UpdateDownloadStartTime();

            if (worker.IsBusy != true)
            {
                worker.DoWork  = new DoWorkEventHandler(worker_DoWorkUnzip);
                worker.RunWorkerCompleted  = new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                worker.RunWorkerAsync();
            }
            break;

    }

}
 

Вот мой код для DoWork и RunWorkerCompleted

 private void worker_DoWorkDownload(object sender, DoWorkEventArgs e)
{
    DownloadFile();
}
private void worker_DoWorkUnzip(object sender, DoWorkEventArgs e)
{
    ExtractFile();
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    GetEndTime();
    GetDuration();
    UpdateDownloadEndTime();
}
 

Что касается моего кода, он продолжает выполнять Dowork одновременно. Что я хочу сделать, так это выполнить Backgroundworker для каждого элемента в моем процессе.

Как я могу это сделать?

Комментарии:

1. Одна из проблем, которые я вижу в приведенном выше коде, заключается в том, что, если рабочий занят, вы не обрабатываете элемент.

2. Я переместил все свои методы внутри dowork, и это сделало свое дело. Хотя я использую dispatchertimer для обновления моей сетки.

Ответ №1:

Попробуйте переместить свой коммутатор в обработчик DoWork и вызвать DownloadFile или другой в блоке if вместо подписки и запуска backgroundworker.

Комментарии:

1. Но в этом коде Datagrid должен обновиться перед выполнением Downloadfile() . Если я помещу swith в свой Dowork, как я могу обновлять свою сетку каждый раз, когда выполняются все случаи?

2. Я поместил свой коммутатор в свой DoWork, но получил сообщение об ошибке, в котором говорится, что вызывающий поток не может получить доступ к этому объекту, потому что он принадлежит другому потоку. ** Эта ошибка появилась при обновлении моей сетки данных. в разделе ** dataGridDownload. ItemsSource = таблица. DefaultView;

3. @KuriyamaMirai, dataGridDownload. Вызвать ((Действие)()=> dataGridDownload. ItemsSource = таблица. DefaultView);

4. @ IL_Agent, я попробовал ваш комментарий, и он действительно работает. Это лучше, чем использовать dispatchertimer. Спасибо

Ответ №2:

Почему бы вместо этого не переключиться на async / await?

 foreach (string item in Processes)
{
  ItemValue = item;
  //Get process code for the process under the selected source
  GetActiveProcess();

  GetStartTime();
  UpdateDownloadStartTime();

  switch (ProcessCode)
  {
    case "Download File":
      await Task.Run(DownloadFile);
      break;

    case "Unzip File":
      await Task.Run(ExtractFile);
      break;
  }

  GetEndTime();
  GetDuration();
  UpdateDownloadEndTime();
}
 

Комментарии:

1. Я поместил свой коммутатор в свой DoWork, но получил сообщение об ошибке, в котором говорится, что вызывающий поток не может получить доступ к этому объекту, потому что он принадлежит другому потоку. ** Эта ошибка появилась при обновлении моей сетки данных. в разделе ** dataGridDownload. ItemsSource = таблица. DefaultView;

2. Вы не можете обновлять элементы управления GUI в фоновом потоке. Элементы управления GUI доступны только в основном потоке.

3. @KuriyamaMirai, dataGridDownload. Вызвать ((Действие)()=> dataGridDownload. ItemsSource = таблица. DefaultView);

Ответ №3:

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

Это означает, что вам нужно по-другому удалять элементы из списка процессов. Удалите первый элемент, как у вас есть, настройте своего рабочего и запустите DoWork, но затем каждый последующий элемент должен быть удален, а рабочий должен быть настроен в завершенном обработчике (worker_RunWorkerCompleted)

Кроме того, вы продолжаете добавлять обработчики событий do work к своему рабочему, даже не удаляя их. И вам нужно только один раз добавить обработчик worker_RunWorkerCompleted к рабочему — не делайте этого для каждого обрабатываемого элемента.