Mam aplikację czasu rzeczywistego, która śledzi zasoby wokół wielu witryn w całym kraju. W ramach tego rozwiązania mam 8 aplikacji klienckich, które aktualizują serwer centralny.Najlepszy sposób na pokonanie limitu czasu WCF
Moje pytanie brzmi: czasami aplikacje tracą połączenie z centralnym serwerem i zastanawiam się, jaki jest najlepszy sposób, aby sobie z tym poradzić? Wiem, że mogłem po prostu zwiększyć maksymalne czasy wysyłania/odbierania, aby poradzić sobie z przekroczeniem limitu czasu, ALE również chcę uzyskać wdzięczne rozwiązanie, jeśli połączenie z serwerem jest wyłączone:
Na przykład nazywam moje usługi w ten sposób :
using (var statusRepository = new StatusRepositoryClient.StatusRepositoryClient())
{
statusId = statusRepository.GetIdByName(licencePlateSeen.CameraId.ToString());
}
myślałem o dodanie try/catch tak ...
using (var statusRepository = new StatusRepositoryClient.StatusRepositoryClient())
{
try
{
statusId = statusRepository.GetIdByName(licencePlateSeen.CameraId.ToString());
}
catch (TimeoutException timeout)
{
LogMessage(timeout);
}
catch (CommunicationException comm)
{
LogMessage(comm);
}
}
Radzenie sobie to w ten sposób nie pozwala mi ponownie uruchomić kod bez konieczności mnóstwo powtórzenia kodu. Ktoś ma jakieś sugestie?
EDYTOWANIE: Patrząc na odpowiedzi Sixto Saez i user24601, posiadanie ogólnego rozwiązania jest lepsze niż rozwiązywanie problemów z przekroczeniem limitu czasu na indywidualnym poziomie wyjątku, ALE ... Myślałem, że poniższe rozwiązanie rozwiąże mój problem (ale doda TON dodatkowych błędów obsługi kodu):
void Method(int statusId)
{
var statusRepository = new StatusRepositoryClient.StatusRepositoryClient()
try
{
IsServerUp();
statusId = statusRepository.GetIdByName(licencePlateSeen.CameraId.ToString());
statusRepository.Close();
}
catch (Exception ex)
{
statusRepository.Abort();
if (ex is TimeoutException || ex is CommunicationException)
{
LogMessage(timeout);
Method(statusId);
}
else
{
throw new Exception(ex.Message + ex.InnerException);
}
}
}
}
bool IsServerUp()
{
var x = new Ping();
var reply = x.Send(IPAddress.Parse("127.0.0.1"));
if (reply == null)
{
IsServerUp();
}
else
{
if (reply.Status != IPStatus.Success)
{
IsServerUp();
}
}
return true;
}
Można napisać funkcję, która sprawdzi, czy serwer jest uruchomiony, w ten sposób można sprawdzić, czy serwer jest uruchomiony, zanim zostanie nawiązane połączenie z repozytorium. Możesz także zajrzeć do wyglądu serwera. – Jethro
Stwórz więc funkcję rekursywną, która nie wyjdzie, dopóki serwery się nie zakończą ... i wyskoczysz przed wywołaniem wcf? Podoba mi się ten pomysł i byłby to mniejszy kod niż powyższa edycja. Twój pomysł zdecydowanie poprawia niezawodność 99%, ale jak poradziłbym sobie, gdyby serwer utracił połączenie między czekiem a wywołaniem metody? –
@Jethro: Najlepsze praktyki odradzają stosowanie metody ping. Zobacz dyskusję tutaj: http://stackoverflow.com/questions/2166356/how-to-check-if-a-wcf-service-is-operational Podstawową ideą jest to, że timeout może być wynikiem zależności usługowej, 't pojawiają się w zdarzeniu ping (takim jak usługa WCF, która współdziała z bazą danych, w której baza danych powoduje przekroczenie limitu czasu). – VoteCoffee