Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: Anthony MastreanОтветов: 5

У меня есть консольное приложение, которое запускается, размещает кучу служб (длительный запуск), а затем ждет, когда клиенты вызовут его. У меня есть интеграционные тесты, которые запускают это консольное приложение и делают "клиентские" вызовы. Как дождаться завершения запуска консольного приложения, прежде чем совершать клиентские вызовы?

Я не хочу делать Thread.Sleep(int), потому что это зависит от времени запуска (которое может измениться), и я теряю время, если запуск происходит быстрее.

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

Я открыт для неудобных решений, таких как заставить консольное приложение записать временный файл, когда он будет готов.

  • В консольном приложении размещаются службы WCF. Клиент выполняет вызовы WCF. Если консольное приложение не завершило запуск, клиент получает исключения Endpoint Not Found. Anthony Mastrean 29.04.2010

timeoutconsole-application

Ответы

Ответ 1 · рейтинг 10 · Chris Taylor

Один из вариантов - создать именованный EventWaitHandle. Это создает объект синхронизации, который можно использовать в процессах. Затем ваши "клиентские" приложения ждут, пока событие не будет сигнализировано, прежде чем продолжить. Как только основное консольное приложение завершило запуск, оно может сигнализировать об этом событии.

http://msdn.microsoft.com/en-us/library/41acw8ct(VS.80).aspx

Например, ваше консольное приложение "Сервер" может иметь следующее. Это не скомпилировано, так что это просто отправная точка :)

using System.Threading;
static EventWaitHandle _startedEvent;
static void main()
{
  _startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted");

  DoLongRunnningInitialization();

  // Signal the event so that all the waiting clients can proceed
  _startedEvent.Set();
}

Затем клиенты будут делать что-то вроде этого

using System.Threading;
static void main()
{
  EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, @"Global\ConServerStarted");

  // Wait for the event to be signaled, if it is already signalled then this will fall throught immediately.
  startedEvent.WaitOne();

//  ... continue communicating with the server console app now ...
}

Ответ 2 · рейтинг 4 · Malfist

Как насчет установки мьютекса и его удаления после завершения запуска. Пусть клиентское приложение подождет, пока оно не сможет захватить мьютекс, прежде чем оно начнет что-то делать.

Ответ 3 · рейтинг 1 · Kyle Alons

Включите проверку готовности в клиентском интерфейсе приложения или сделайте так, чтобы оно возвращало ошибку "Не готово", если оно вызывается до того, как оно будет готово.

Ответ 4 · рейтинг 1 · Sam Harwell

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

  • Разместите эту службу в качестве первой операции клиентского приложения.
  • Используйте привязку net.tcp или net.pipe, так как они запускаются очень быстро.
  • Сохраняйте эту службу как можно более простой, чтобы она оставалась доступной до тех пор, пока консольное приложение не завершит работу.

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

Ответ 5 · KMån

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

  • Другая возможность может заключаться в том, что вы вычисляете среднее время, необходимое консоли для загрузки служб, и используете это время в своем тестовом приложении; ну просто мысли вслух!

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы