Подтвердить что ты не робот

С# следует создать один рабочий или много?

Я один из тех случайных программистов, поэтому у меня нет таких знаний о наилучшей практике программирования.

У меня есть приложение, в котором в настоящее время используется 4 справочника.

Поэтому я объявляю их:

private BackgroundWorker bw1;
private BackgroundWorker bw2;
private BackgroundWorker bw3;
private BackgroundWorker bw4;

Затем настройте их:

bw1 = new BackgroundWorker();
bw1.WorkerReportsProgress = true;
bw1.DoWork += new DoWorkEventHandler(bw1_DoWork);
bw1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw1_RunWorkerCompleted);
bw1.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw2 = new BackgroundWorker();
bw2.WorkerReportsProgress = true;
bw2.DoWork += new DoWorkEventHandler(bw2_DoWork);
bw2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw2_RunWorkerCompleted);
bw2.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw3 = new BackgroundWorker();
bw3.WorkerReportsProgress = true;
bw3.DoWork += new DoWorkEventHandler(bw3_DoWork);
bw3.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw3_RunWorkerCompleted);
bw3.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw4 = new BackgroundWorker();
bw4.WorkerReportsProgress = true;
bw4.DoWork += new DoWorkEventHandler(bw4_DoWork);
bw4.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw4_RunWorkerCompleted);
bw4.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

И затем я использую bw1.RunWorkerAsync(), bw2.RunWorkerAsync() и т.д....

Дело в том, что я никогда не называю их одновременно, они вызываются в разных точках довольно линейным способом.

Итак, мой вопрос: лучше ли иметь много "предварительно настроенных" фоновых работников или иметь их и изменять события DoWork и RunWorkerCompleted в соответствии с тем, что я хочу сделать?

4b9b3361

Ответ 1

С архитектурной точки зрения лучше всего иметь отдельный фоновый рабочий для каждой фоновой задачи, который логически не связан с другими задачами класса.

Ответ 2

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

public void SomeEventHandlerMaybe(object sender, EventArgs e) {
  // do something

  var bw = new BackgroundWorker();
  bw.ReportsProgress = true;
  bw.DoWork += delegate {
    // do work. You can use locals from here
  };
  bw.ProgressChanged += delegate { ... };
  bw.RunWorkerCompleted += delegate {
    // do something with the results.
  };
  bw.RunWorkerAsync();
}

Что-то вроде этого. Это имеет то преимущество, что у вас есть весь код, который что-то делает с или в фоновом рабочем месте в одном месте и примерно в правильном порядке.

Ответ 3

В целом разумно использовать несколько потоков, если это помогает с более эффективным использованием ресурсов в вашей системе. Для задач с интенсивным использованием процессора один поток на ядро ​​процессора является хорошей отправной точкой. Для интенсивных задач ввода-вывода у вас может быть много чего большего.

Если у вас есть гибкость в использовании .NET 4, я бы рассмотрел "Библиотека задач" вместо BackgroundWorker. По умолчанию он будет принимать относительно разумные решения относительно того, сколько потоков будет выполняться одновременно в дополнение к упрощенной модели программирования.

Ответ 4

Выполнение вашей обработки с использованием BackgroundWorker означает, что вы делаете это в отдельном потоке. Поэтому, если вам не нужна многопоточность, нет необходимости в отдельных персональных работниках. Если вы ожидаете завершения после того, как вы начнете работу с каждым из ваших сотрудников, вы можете иметь только одного работника. Он также может удалить часть дублирования кода...

Ответ 5

Вы запускаете работников для некоторых вычислительных целей. Если расчет одного вызова используется или каким-либо образом зависит от другого, вы можете использовать более одного рабочего, чтобы добиться более высокой производительности (кстати, это тоже предмет измерения). Если вам просто нужно выполнить 4 задания и запустить их в отдельном потоке, чтобы не блокировать основной пользовательский интерфейс, один рабочий - довольно хорошее решение.