Обеспечивает ли BackgroundWorker настоящую многопоточность?

Учась создавать многопоточные приложения WPF, я читал о некоторых ограничениях в использовании BackgroundWorker, которые были для меня не очень понятны. Пожалуйста, помогите мне понять:

Если я хочу, чтобы за кулисами UI работал не один поток, а, может быть, несколько, запускающихся и заканчивающихся независимо друг от друга, подойдет ли в таком случае BackgroundWorker? Могу ли я иметь несколько экземпляров BackgroundWorker?

Проще говоря, обеспечивает ли BackgroundWorker многопоточность, а не просто двухпоточность?


person rem    schedule 13.02.2010    source источник
comment
У вас есть ссылка на ограничения, о которых вы читали?   -  person Mark Byers    schedule 13.02.2010
comment
@Mark Byers Например, этот абзац (из книги Мэтью Макдональда Pro WPF в C# 2008): Примечание. BackgroundWorker идеален, если у вас есть одна асинхронная задача, которая выполняется в фоновом режиме от начала до конца (с дополнительной поддержкой отчетов о ходе выполнения и отмена). Если вы имеете в виду что-то другое — например, асинхронную задачу, которая выполняется на протяжении всего жизненного цикла вашего приложения, или асинхронную задачу, которая взаимодействует с вашим приложением, пока оно выполняет свою работу, вам потребуется разработать индивидуальное решение с использованием .NET. поддержка резьбы.   -  person rem    schedule 13.02.2010
comment
Я думаю, что это больше вопрос того, что считается хорошим дизайном, а не того, что технически возможно. Вы можете создать много фоновых рабочих, но это может быть не лучшим способом решения вашей проблемы.   -  person Mark Byers    schedule 13.02.2010


Ответы (4)


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

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

Использовать BackgroundWorker на самом деле довольно просто:

var worker1 = new System.ComponentModel.BackgroundWorker();
worker1.DoWork += (sender,e) => Thread.Sleep(10000);
worker1.RunWorkerCompleted += (sender,e) => MessageBox.Show("Worker1 Finished!");
worker1.RunWorkerAsync();
person LBushkin    schedule 13.02.2010

Указанные вами ограничения (из Pro WPF) проистекают из того факта, что BGW использует ThreadPool, поэтому все правила и рекомендации относительно потоков ThreadPool действительно применяются.

person Henk Holterman    schedule 13.02.2010
comment
Спасибо за полезную информацию и ссылку +1 - person rem; 15.02.2010

Если вы создадите много экземпляров BackgroundWorker, вы получите много потоков, однако один экземпляр обеспечивает только одну фоновую задачу.

person Pent Ploompuu    schedule 13.02.2010

Да, внутренне фоновый рабочий вызывает BeginInvoke для предоставленного вам делегата. Это приведет к тому, что ваш делегат будет помещен в пул потоков в среде CLR.

person Steve Sheldon    schedule 13.10.2010