Как обрабатывать исключения потоков в основном потоке, блокировать всех рабочих и уведомлять их о завершении? - PullRequest
1 голос
/ 09 июля 2010

У меня есть служба Windows, выполняющая некоторую повторяющуюся работу (вызовы wcf) после программной регистрации на веб-сервере. Все вызовы вызываются через различные потоки, работающие зависимо параллельно, но если, например, соединение потеряно или перезапускается iis, следовательно, управление сеансом inproc указывает мне повторно войти в систему, я хочу обработать это исключение, остановить все другие потоки , распространить исключение до основного потока, повторить попытку входа в систему и в случае успеха сигнализировать о перезапуске всех потоков.

Мое основное приложение - что-то вроде следующего. Я вхожу в систему, я запускаю двух рабочих, и механизм обработки исключений в основном потоке находится на рассмотрении:

        IFileManagerService fileManagerService = new FileManagerService();
        IJobManagerService  jobManagerService  = new JobManagerService();

        WindowsServiceSettings.AuthenticationService.Login(WindowsServiceSettings.Credentials.Split(':')[0], WindowsServiceSettings.Credentials.Split(':')[1]);

        WriteToLogFile("Service Started at " + DateTime.Now);

        fileManagerService.Start();
        jobManagerService.Start();

Могу ли я реализовать это с помощью ручек ожидания и как я собираюсь?

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 10 июля 2010

Для проекта .Net 3.5 я бы использовал метод обратного вызова из рабочего потока, чтобы сообщить основному потоку о наличии проблемы. Пусть каждый работник вызывает отдельный метод обратного вызова «heartbeat», который периодически проверяет у основного потока разрешение на продолжение; рабочий может быть вызван из разных мест в цикле обработки.

Если основной поток получает обратный вызов с ошибкой, он может настроить метод heartbeat на возврат индикации остановки, позволяя каждому рабочему потоку безопасно остановить себя. Когда работник останавливается, он вызывает обратный вызов завершения, который передает ManagedThreadId потока, который основной удаляет из коллекции активных потоков. Как только счет сбора равен нулю, все работники готовы. Это позволяет избежать необходимости полагаться на Thread.Abort ().

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

1 голос
/ 09 июля 2010

Во-первых, вам нужен способ распространять исключения между потоками. Безусловно, самый простой способ сделать это - превратить ваши дочерние потоки в Task объекты. Затем вы можете дать этим задачам продолжение , чтобы определить, не произошла ли какая-либо из них.

Второе, что вам нужно, это способ отменить другие темы. Используйте кооператив Отмена с тем же CancellationToken. Когда продолжение задачи обнаруживает ошибку, оно должно отменить все остальные потоки (и дождаться их завершения).

С этого момента достаточно просто повторно войти в систему, а затем перезапустить задачи (включая регистрацию себя в качестве продолжения задачи для новых задач).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...