6

पर सर्वर से बात करने की कोशिश करते रहें तो मेरा एप्लिकेशन किसी सर्वर (कोई समस्या नहीं) के साथ अनुरोध/प्रतिक्रिया का आदान-प्रदान कर रहा है, जब तक कि इंटरनेट कनेक्शन कुछ सेकंड के लिए मर जाता है, फिर वापस आ जाता है। तो फिर इस तरह की एक कोड:जब इंटरनेट डाउन

response = (HttpWebResponse)request.GetResponse();

KeepAliveFailure आदि

अब ReceiveFailure की तरह एक स्थिति, ConnectFailure, साथ, एक अपवाद फेंक देते हैं, यह काफी महत्वपूर्ण है कि यदि इंटरनेट कनेक्शन वापस आता है, मैं कर रहा हूँ है सर्वर के साथ संवाद जारी रखने में सक्षम, अन्यथा मुझे शुरुआत से फिर से शुरू करना होगा और इसमें काफी समय लगेगा।

इंटरनेट वापस आने पर आप इस संचार को फिर से शुरू करने के बारे में कैसे जाएंगे?

फिलहाल, मैं सर्वर के साथ संवाद करने की संभावना की जांच कर रहा हूं, जब तक यह संभव न हो (कम से कम सैद्धांतिक रूप से)। मेरे कोड का प्रयास इस तरह दिखता है:

try 
{ 
    response = (HttpWebResponse)request.GetResponse(); 
} 
catch (WebException ex) 
{ 
    // We have a problem receiving stuff from the server. 
    // We'll keep on trying for a while 
    if (ex.Status == WebExceptionStatus.ReceiveFailure || 
     ex.Status == WebExceptionStatus.ConnectFailure || 
     ex.Status == WebExceptionStatus.KeepAliveFailure) 
    { 
     bool stillNoInternet = true; 

     // keep trying to talk to the server 
     while (stillNoInternet) 
     { 
      try 
      { 
       response = (HttpWebResponse)request.GetResponse(); 
       stillNoInternet = false; 
      } 
      catch 
      { 
       stillNoInternet = true; 
      } 
     } 
    } 
} 

हालांकि, समस्या यह है कि दूसरी कोशिश पकड़ बयान एक अपवाद फेंक इंटरनेट वापस आ गया है, जब भी रखता है।

मैं क्या गलत कर रहा हूं? क्या इसे ठीक करने के लिए जाने का कोई और तरीका है?

धन्यवाद!

+0

आपके प्रश्न का उत्तर नहीं है, लेकिन यदि आपका कनेक्शन लंबे समय तक नीचे चला जाता है, तो आपके पास वर्तमान में इसे मारने का कोई अच्छा तरीका नहीं है ... – Paddy

+0

सर्वर में 5 मिनट का टाइमआउट भी है, इसलिए यदि कनेक्शन वास्तव में 5 मिनट से अधिक समय तक नीचे चला जाता है, तो यह इसे मारने का तरीका है। – Andrei

+0

क्यों आप हर 10 मिनट में कनेक्शन के परीक्षण के लिए टाइमर सेट नहीं करते हैं, फिर भी जो कुछ भी कर रहे थे उसे पुनरारंभ करें? या हो सकता है कि हर बार एक कनेक्टफेलर एक मिनट तक प्रतीक्षा समय बढ़ाए। –

उत्तर

15

आपको हर बार अनुरोध को फिर से बनाना चाहिए, और आपको प्रत्येक लेट्री के बीच प्रतीक्षा के साथ लूप में रीट्रीज़ निष्पादित करना चाहिए। प्रतीक्षा समय प्रत्येक विफलता के साथ क्रमिक रूप से बढ़ना चाहिए।

उदा।

ExecuteWithRetry (delegate { 
    // retry the whole connection attempt each time 
    HttpWebRequest request = ...; 
    response = request.GetResponse(); 
    ... 
}); 

private void ExecuteWithRetry (Action action) { 
    // Use a maximum count, we don't want to loop forever 
    // Alternativly, you could use a time based limit (eg, try for up to 30 minutes) 
    const int maxRetries = 5; 

    bool done = false; 
    int attempts = 0; 

    while (!done) { 
     attempts++; 
     try { 
      action(); 
      done = true; 
     } catch (WebException ex) { 
      if (!IsRetryable (ex)) { 
       throw; 
      } 

      if (attempts >= maxRetries) { 
       throw; 
      } 

      // Back-off and retry a bit later, don't just repeatedly hammer the connection 
      Thread.Sleep (SleepTime (attempts)); 
     } 
    } 
} 

private int SleepTime (int retryCount) { 
    // I just made these times up, chose correct values depending on your needs. 
    // Progressivly increase the wait time as the number of attempts increase. 
    switch (retryCount) { 
     case 0: return 0; 
     case 1: return 1000; 
     case 2: return 5000; 
     case 3: return 10000; 
     default: return 30000; 
    } 
} 

private bool IsRetryable (WebException ex) { 
    return 
     ex.Status == WebExceptionStatus.ReceiveFailure || 
     ex.Status == WebExceptionStatus.ConnectFailure || 
     ex.Status == WebExceptionStatus.KeepAliveFailure; 
} 
+0

धन्यवाद क्रिस। महान समाधान और कोड। – Andrei

0

यदि कनेक्शन वापस आने पर यह अभी भी कर रहा है - तो मेरा अनुमान है कि यह केवल उसी परिणाम को फिर से लौट रहा है।

आप हर बार अनुरोध को फिर से प्रयास करने का प्रयास करना चाहेंगे, इसके अलावा मुझे कोड या तर्क के साथ बहुत गलत नहीं दिख रहा है। इस तथ्य के अलावा कि आप हमेशा इस धागे को अवरुद्ध कर रहे हैं। लेकिन फिर यह ठीक हो सकता है अगर यह स्वयं में एक कार्यकर्ता धागा है।

1

मुझे लगता है कि तुम क्या करने की कोशिश कर रहे हैं इस:

HttpWebResponse RetryGetResponse(HttpWebRequest request) 
{ 
    while (true) 
    { 
     try 
     { 
      return (HttpWebResponse)request.GetResponse(); 
     } 
     catch (WebException ex) 
     { 
      if (ex.Status != WebExceptionStatus.ReceiveFailure && 
       ex.Status != WebExceptionStatus.ConnectFailure && 
       ex.Status != WebExceptionStatus.KeepAliveFailure) 
      { 
       throw; 
      } 
     } 
    } 
} 

आप कुछ है कि आप जब कुछ विफल रहता है क्या करना चाहते हैं के रूप में इस के बारे में सोच के बजाय तो विफलता पर कुछ पुन: प्रयास करना चाहते हैं, इसके बजाय इसके बारे में सोचें जब तक कि आप सफल न हों। (या एक विफलता जिसे आप पुनः प्रयास नहीं करना चाहते हैं)। उपरोक्त प्रतिक्रिया तब तक जारी रहेगी जब तक कोई प्रतिक्रिया वापस नहीं आती है या एक अलग अपवाद फेंक दिया जाता है।

किसी भी प्रकार की अधिकतम पुनः प्रयास सीमा (उदाहरण के लिए 1 घंटे के बाद पुनः प्रयास करना) शुरू करना भी एक अच्छा विचार होगा।