Многопоточный сервис, BackgroundWorker vs ThreadPool?

Без обид, как один разработчик другому, я боюсь, что ваша идея кажется ужасно неэффективной. Мне кажется, что вместо объединения баз данных SQLite вы, вероятно, должны хранить несколько таблиц в одном файле базы данных.

Однако, если я ошибаюсь, я думаю, вы могли бы использовать ATTACH базы данных, а затем использовать VIEW для упрощения ваши запросы. Или сделайте таблицу в памяти и скопируйте все данные (но это даже худшая производительность, особенно если у вас большие базы данных)

24
задан Community 23 May 2017 в 10:34
поделиться

2 ответа

Значение в BackgroundWorker заключается в том, что он может вызывать свои события ProgressChanged и RunworkerCompleted в потоке, создавшем его экземпляр. Что делает его очень удобным в программах, которые не поддерживают свободную многопоточность.

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

Существует соединение, Winforms и WPF являются библиотеками классов, в которых есть проблема с многопоточностью. Оба реализуют графические интерфейсы пользователя и графические пользовательские интерфейсы на основе Windows, в основном поточно-ориентированные. Окна Windows могут быть обновлены только из потока, который их создал. Другими словами, эти пользовательские поставщики синхронизации существуют, потому что они крайне необходимы. Также следует отметить, что они работают, используя преимущества работы потоков пользовательского интерфейса. Поток пользовательского интерфейса выполняет код, управляемый событиями, прокачивая цикл сообщений для получения уведомлений. Поставщик синхронизации может внедрять вызовы в обработчики событий, используя этот механизм. Это не случайно.

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

34
ответ дан Wai Ha Lee 23 May 2017 в 10:34
поделиться

Я думаю, что ваш третий выбор лучше. Я делал аналогичные вещи со службами Windows в .Net 3.5 и обнаружил, что создание собственных потоков - хороший способ, особенно с потоками, которые взаимодействуют с веб-службами.

Я создаю рабочий экземпляр и отправляю ему обратный вызов, который сигнализирует службе, когда она завершена. Я храню готовые к запуску потоки в Queue и очищаю их в соответствии с максимальным числом одновременных потоков, которое я хочу. Если все, что вас волнует, это количество запущенных сервисов, вы можете отслеживать их с помощью простого счетчика. Я предпочитаю хранить каждый работающий рабочий экземпляр в ключе Dictionary, указанном потоком ManagedThreadId, чтобы я мог легко сигнализировать о каждом экземпляре, если хочу аккуратно его выключить. Также удобно опрашивать запущенные экземпляры для проверки статуса.

2
ответ дан Ed Power 23 May 2017 в 10:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: