Как продолжить выполнение кода только после завершения службы Windows?

#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: имхо, служба ни к чему не привязана: она запускается, создавая и освобождая мьютекс, стоп. Клиент подключен к службе, но это выбор. Я ошибаюсь? 🙂