#c# #multithreading #windows-services #named-pipes
#c# #многопоточность #windows-services #именованные каналы
Вопрос:
У меня есть служба Windows, которая выполняет довольно длительную задачу. На данный момент я создаю новый поток, который выполняет метод, который отключается и вызывает эту службу Windows. Этот код выглядит следующим образом:
Thread thread = new Thread(new ThreadStart(ExecyuteLongRunningMethod));
thread.Start();
thread.Join();
Выше в стеке вызовов (когда этот код выполнен) появляется окно сообщения с указанием результата операции.
Однако, во время выполнения этого блока кода ( ExecuteLongRunningMethod
вызывает Windows svc) появляется окно с сообщением о том, что в результате операции ничего не изменилось, но поскольку это произошло до завершения приведенного выше блока кода, появляется неправильное окно с сообщением.
Таким образом, вопрос в том, каким был бы правильный способ продолжить выполнение только в приложении winforms (это то, что вызывает Windows svc), ТОЛЬКО когда служба Windows завершена? Я думаю, что описанный выше подход неверен, поскольку поток вызовет службу Windows (другой процесс), поэтому, пока служба Windows выполняет свои задачи, мой код (приложение winforms) будет продолжаться. Требуется либо какая-то сигнализация, либо что-то вроде именованных каналов?
Приложение находится в .NET 3.5.
Спасибо
Ответ №1:
Предоставьте статус выполнения вашей службы через WCF API и вызовите его с помощью netTcp или именованных каналов, вы можете опросить службу или использовать обратный вызов WCF.
Ответ №2:
Почему вы не используете BackgroundWorker, чтобы вы могли установить событие для его завершения?
В запущенном методе Backgroundworker вы можете запустить службу и дождаться события ручного сброса (например) или мьютекса, и, получив это, вы можете выйти из метода main.
Итак, в вашем главном потоке (например, в пользовательском интерфейсе) возникает событие OnCompleted, и работа выполнена…
В вашем приложении добавьте Backgroundworker и назовите его bgw
.
Тогда вы можете сделать:
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// 1. Run the service
// 2. Wait for mutex
}
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Here you can handle the end of the service
// and return the status in main thread
}
Комментарии:
1. Спасибо, я посмотрю на это. Как это будет работать? Я имею в виду, что службе Windows нужно было бы подать какой-то сигнал, чтобы приложение winforms знало, что оно завершено.
2. Значит, мне не нужно будет изменять Windows svc? Я попробую.
3. @dotnetdev: вы должны изменить svc следующим образом: когда вы запускаете его, он должен создать (или стать владельцем) мьютекса
mut
и освободить его, когда завершит свою работу. Мьютексmut
— это тот, который вы ожидаете в вашем backgroundworker…4. Вы создаете тесную связь между службой и клиентом, когда в этом нет необходимости.
5. @Llloyd: имхо, служба ни к чему не привязана: она запускается, создавая и освобождая мьютекс, стоп. Клиент подключен к службе, но это выбор. Я ошибаюсь? 🙂