Я работаю над своим первым проектом Windows Service, который включает в себя некоторые основные потоки / параллелизм. Пока это было довольно интенсивно, но я постепенно начинаю понимать многопоточность (я думаю, мы посмотрим на это ...).
У меня есть служба Windows, которая будет содержать 2 слабо связанных рабочих потока. Поток A будет загружать файлы с FTP-сервера, разархивировать / подготавливать их и сохранять в другом каталоге, где поток B будет наблюдать за FileSystemWatcher. Поток B проанализирует файлы, выполнит несколько действий с данными, сделает несколько http-вызовов и, наконец, заархивирует и удалит файлы из рабочего каталога.
Я только начинаю работу, и проблема, с которой я сейчас сталкиваюсь, заключается в том, как дождаться возврата как потока A, так и потока B. Я посмотрел на этот вопрос: Thread.Join на несколько потоков с таймаутом и у меня была идея.
Проблема в том, что если мы ожидаем, что потоки x вернутся с секундным таймаутом ax для каждого из них, при достаточном количестве потоков сервис может оказаться невосприимчивым даже при нормальной работе (я прочитал тайм-аут до того, как SCM жалуется, составляет 30 секунд, верно ?). Кроме того, если мы решим эту проблему, отслеживая время, оставшееся до присоединения при циклическом переключении потоков, чем дольше мы ждем потоки в начале сбора рабочих, тем меньше времени остается для возврата оставшихся потоков - так что в конечном итоге при достаточном количестве потоков служба будет не отвечать, даже если все потоки возвращаются в течение ожидаемого периода времени.
В этом случае я, вероятно, просто буду нитью. Присоединяюсь и к А, и к В по истечении 14 секунд, потому что у меня всего два рабочих, а 14 секунд кажется достаточным временем для возвращения обоих.
Если бы у меня было переменное количество рабочих потоков (скажем,> 8), стоило бы сделать что-то подобное? Будет ли это работать надежно?
Примечание: не используйте следующее - это плохая идея на нескольких уровнях. Смотрите ответы
protected override void OnStop()
{
// the service is stopping - set the event
Worker.ThreadStopEvent.Set();
// stop the threads
Parallel.ForEach(_workerThreads, t =>
{
t.Join(new TimeSpan(0, 0, 28));
});
}