Значение в BackgroundWorker
заключается в том, что он может вызвать свои события ProgressChanged
и RunworkerCompleted
в потоке, создавшем его экземпляр. Что делает его очень удобным в программах, которые не поддерживают бесплатную многопоточность.
Чтобы это работало должным образом, необходимо, чтобы свойство SynchronizationContext.Current
ссылалось на провайдера синхронизации не по умолчанию. Поставщик, который отвечает за маршалинг вызовов из одного потока в другой. .NET Framework имеет два доступных поставщика: System.Windows.Forms.WindowsFormsSynchronizationContext
и System.Windows.Threading.DispatcherSynchronizationContext
. Эти провайдеры обрабатывают синхронизацию соответственно для Winforms и WPF.
Существует соединение, Winforms и WPF являются библиотеками классов, в которых есть проблема с многопоточностью. Оба реализуют графические интерфейсы и графические пользовательские интерфейсы на основе Windows, по сути, небезопасные. Окна Windows могут быть обновлены только из потока, который их создал. Другими словами, эти пользовательские поставщики синхронизации существуют, потому что они крайне необходимы. Также следует отметить, что они работают, используя преимущества работы потоков пользовательского интерфейса. Поток пользовательского интерфейса выполняет код, управляемый событиями, прокачивая цикл сообщений для получения уведомлений. Поставщик синхронизации может внедрять вызовы в обработчики событий, используя этот механизм. Это не случайно.
Вернемся к теме, у службы Windows такой возможности нет. Он не имеет графического интерфейса и не устанавливает пользовательский поставщик синхронизации. Таким образом, BackgroundWorker
не предоставляет функции, полезной для службы. Без пользовательского поставщика синхронизации поставщик по умолчанию просто запускает события в потоке потоков. Что бесполезно, вы также можете запустить событие из вашего рабочего потока. Получить события для запуска в другом конкретном потоке очень сложно, если только вы не воссоздаете механизм цикла сообщений или не подключаетесь к соединению Winforms и не создаете смоделированный поток пользовательского интерфейса, используя невидимое окно. Что не является чем-то необычным, кстати.