2010-04-29 12 views
7

Mam aplikację konsoli, która uruchamia się, obsługuje kilka usług (długotrwałe uruchamianie), a następnie czeka na klientów, aby do niego zadzwonić. Mam testy integracyjne, które uruchamiają tę aplikację konsolową i wykonują połączenia "klienckie". Jak mogę poczekać, aż aplikacja konsoli zakończy uruchamianie przed wykonaniem połączeń klienta?Jak mogę poczekać, aż aplikacja konsoli będzie bezczynna?

Chcę uniknąć wykonywania Thread.Sleep(int), ponieważ zależy to od czasu uruchomienia (który może ulec zmianie) i tracę czas, jeśli uruchomienie jest szybsze.

Process.WaitForInputIdle działa tylko w aplikacjach z interfejsem użytkownika (i potwierdziłem, że w tym przypadku zgłasza wyjątek).

Jestem otwarty na niezręczne rozwiązania, takie jak, , czy aplikacja konsolowa zapisze plik tymczasowy, gdy będzie gotowy.

+0

Aplikacja konsoli obsługuje usługi WCF. "Klient" wykonuje połączenia WCF. Jeśli aplikacja konsoli nie została zakończona, klient otrzymuje wyjątki Nie znaleziono punktów końcowych. –

Odpowiedz

10

Jedną opcją jest utworzenie nazwy EventWaitHandle. Tworzy to obiekt synchronizacji, który można wykorzystać w różnych procesach. Następnie aplikacje "oczekujące" czekają, aż zdarzenie zostanie zasygnalizowane przed kontynuowaniem. Gdy główna aplikacja konsoli zakończy rozruch, może zasygnalizować to wydarzenie.

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

Jako przykład aplikacja konsoli „Serwer” może mieć następujące. To nie jest kompilowany więc jest to tylko punkt wyjścia :)

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(); 
} 

Klienci będą wtedy robi coś takiego

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

Co to nazwa "zrobić"? Użyłem nazwy "MyCompany \ HostStarted", a aplikacja konsolowa rzuciła wyjątek DirectoryNotFound! –

+3

Powinienem był o tym wspomnieć. Prefiks Global \ or Local \ kontroluje zasięg zdarzenia. Global \ sprawia, że ​​zdarzenie "visibile" we wszystkich sesjach, podczas gdy Local \ sprawi, że będzie ono widoczne tylko w bieżącej sesji. To ważne rozróżnienie, gdy aplikacja działa na przykład w sesji serwera terminali, gdzie możesz chcieć użyć opcji Lokalnie \ w zależności od wymagań. –

+1

to jest niesamowite i okropne. kocham to. –

1

Dołączenie jest gotowe do sprawdzenia w interfejsie klienta aplikacji, lub zwróci błąd "nie gotowy", jeśli zostanie wywołany, zanim będzie gotowy.

+0

Więc aplikacja musiałaby sprawdzić pętlę, dopóki nie zwróci błędu "I'm not ready"? nie jestem pewien, czy to dobre podejście ... – Jack

0
  • Ponieważ dwa (aplikacja konsoli, i integracja testy aplikacja, która sprawia, że ​​klient wywołuje - jak rozumiem) to oddzielna aplikacja, więc nie powinno być mechanizmem - most - który powie grę jako mediator (gniazdo, zewnętrzny plik, rejestr itp.).

  • Inną możliwością może być znalezienie średniego czasu, jaki zajmuje konsola, aby załadować usługi i wykorzystać ten czas w aplikacji testowej; cóż, po prostu głośno myślę!

4

A co z ustawianiem muteksu i usuwaniem go po uruchomieniu. Niech aplikacja kliencka poczeka, aż będzie mogła pobrać muteks, zanim zacznie robić różne rzeczy.

+0

Podobny co do udzielonej odpowiedzi, jednak użycie EventWaitHandle pozwoli wielu aplikacjom na synchronizację w głównej aplikacji. –

1

Tworzenie usług WCF, które można użyć do wysyłania zapytań stanu połączenia proces serwera. Uruchom tę usługę tylko wtedy, gdy konkretne polecenie zostanie przekazane w wierszu poleceń. Następujące cechy zapewniają bardzo szybkie uruchomienie tej usługi:

  • Host Usługa ta jako pierwsza działanie aplikacji klienckiej
  • Użyj Net.TCP lub netto.Wiązanie rury bo zaczną bardzo szybko
  • zachować tę usługę tak proste, jak to możliwe, aby upewnić się, że tak długo, jak aplikacja konsola nie kończy, to pozostają dostępne

Biegacz test może próbować połączyć do tej usługi. Spróbuj ponownie, jeśli zakończy się niepowodzeniem, dopóki aplikacja konsoli nie zakończy działania lub upłynie odpowiednio krótki czas oczekiwania. Tak długo, jak aplikacja konsoli nie kończy się nieoczekiwanie, możesz polegać na tej usłudze w celu dostarczenia dodatkowych informacji przed rozpoczęciem testów w stosunkowo krótkim czasie.

+0

Zbyt dużo pracy, obsługujemy to jako usługę w produkcji i nigdy nie mamy tego rodzaju problemów z wyścigami. –

Powiązane problemy