2017-07-16 36 views
0

我實際上面臨一個httpWebResponse問題,它會阻止我的線程。GetResponse()和WebException殺死我的線程

我每2秒鐘在一個循環線程中調用ApiCall方法。這在大部分時間都適用。但有時request.GetResponse()拋出WebException並停止我的主線程循環。它凍結了應用程序而不會崩潰它。如果不正常工作,可以重試5次(MaxRetries)。我不明白髮生了什麼事。

以下是ApiCall方法的代碼部分。我真的不知道它的工作原理。於是在這裏和那裏找到了一些代碼。我必須錯過什麼......但是什麼?

public T CallWithJsonResponse<T>(string uri, bool hasEffects, params Tuple<string, string>[] headers) 
    { 
     if (simulate && hasEffects) 
     { 
      Debug.WriteLine("(simulated)" + GetCallDetails(uri)); 
      return default(T); 
     } 

     Debug.WriteLine(GetCallDetails(uri)); 
     var request = HttpWebRequest.CreateHttp(uri); 
     foreach (var header in headers) 
     { 
      request.Headers.Add(header.Item1, header.Item2); 
     } 
     HttpWebResponse response = null; 
     request.Timeout = 300000; 

     for (int i = 0; i < MaxRetries; i++) 
     { 

      try 
      { 
       response = null; 
       using (response = (HttpWebResponse)request.GetResponse()) 
       { 
        if (response.StatusCode == HttpStatusCode.OK) 
        { 
         try 
         { 
          using (var sr = new StreamReader(response.GetResponseStream())) 
          { 
           var content = sr.ReadToEnd(); 
           var jsonResponse = JsonConvert.DeserializeObject<ApiCallResponse<T>>(content); 
           sr.Close(); 
           response.Close(); 

           if (jsonResponse.success) 
           { 
            //GC.Collect(); 
            GC.WaitForPendingFinalizers(); 
            return jsonResponse.result; 
           } 
           else 
           { 

            Console.WriteLine(new Exception(jsonResponse.message.ToString())); 

           } 
          } 
         } 
         catch (Exception ex) 
         { 

          Console.WriteLine("Error - Call Details=" + GetCallDetails(uri) + "Exeption: " + ex.ToString()); 

         } 
        } 
        else 
        { 
         Console.WriteLine("Error - StatusCode=" + response.StatusCode + " Call Details=" + GetCallDetails(uri)); 

        } 
       } 
      } 
      catch (WebException wex) 
      { 
       if (wex.Response != null) 
       { 
        Console.WriteLine("ERROR (web exception, response generated): " + Environment.NewLine + new StreamReader(wex.Response.GetResponseStream()).ReadToEnd()); 
       } 
       else 
       { 
        Console.WriteLine("ERROR (web exception, NO RESPONSE): " + wex.Message + wex.StackTrace); 
       } 
       Console.WriteLine("Error - Call Details=" + GetCallDetails(uri)); 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Error - Call Details=" + GetCallDetails(uri) + "Exception: " + ex.ToString()); 
      } 
     } 
     return default(T); 
    } 

private static string GetCallDetails(string uri) 
    { 
     StringBuilder sb = new StringBuilder(); 
     var u = new Uri(uri); 
     sb.Append(u.AbsolutePath); 
     if (u.Query.StartsWith("?")) 
     { 
      var queryParameters = u.Query.Substring(1).Split('&'); 
      foreach (var p in queryParameters) 
      { 
       if (!(p.ToLower().StartsWith("api") || p.ToLower().StartsWith("nonce"))) 
       { 
        var kv = p.Split('='); 
        if (kv.Length == 2) 
        { 
         if (sb.Length != 0) 
         { 
          sb.Append(", "); 
         } 

         sb.Append(kv[0]).Append(" = ").Append(kv[1]); 
        } 
       } 
      } 
     } 
     return sb.ToString(); 
    } 
+0

我不清楚你有什麼問題,以及你的問題是什麼。 – mjwills

+0

請更新您的文章以包含'GetCallDetails'方法的源代碼。 – mjwills

+0

好吧,我想讓代碼在發生WebException後繼續運行。但WebException似乎停止當前的線程並凍結我的應用程序。其他例外情況只需在控制檯中寫入一些文本並且應用程序繼續運行。 ApiCall不是強制性的。如果失敗了,不管。下一次嘗試將在下一個循環完成。但是對於WebException,下一個循環永遠不會到來...... – TiB

回答

0

我建議改變:

catch (WebException wex) 
{ 
    if (wex.Response != null) 
    { 
     Console.WriteLine("ERROR (web exception, response generated): " + Environment.NewLine + new StreamReader(wex.Response.GetResponseStream()).ReadToEnd()); 
    } 
    else 
    { 
     Console.WriteLine("ERROR (web exception, NO RESPONSE): " + wex.Message + wex.StackTrace); 
    } 
    Console.WriteLine("Error - Call Details=" + GetCallDetails(uri)); 

} 

到:

catch (WebException wex) 
{ 
    try 
    { 
     if (wex.Response != null) 
     { 
      Console.WriteLine("ERROR (web exception, response generated): " + Environment.NewLine + 
           new StreamReader(wex.Response.GetResponseStream()).ReadToEnd()); 
     } 
     else 
     { 
      Console.WriteLine("ERROR (web exception, NO RESPONSE): " + wex.Message + wex.StackTrace); 
     } 
     Console.WriteLine("Error - Call Details=" + GetCallDetails(uri)); 
    } 
    catch (Exception bob) 
    { 
     // Ignore exceptions here 
    } 
} 

然後在catch (Exception bob)行設置斷點 - 看到爲什麼現有的catch塊失敗。

+0

非常感謝,我會嘗試。 – TiB

0

好吧,它似乎工作正常,我試圖消耗每一個像你說的斯彭德的迴應。 而且我也把try catch放在WebException catch裏面,就像你說的mjwills一樣,但它永遠不會被捕獲。所以我認爲消費每一個迴應都是解決我的問題的方法。謝謝 !現在我需要在一週內監控應用程序,看它是否健壯。

0

沒有......它沒有改變任何東西。我創建了一些方法來檢查WebException發生後該線程是否仍然存在。你猜怎麼着! try/catch工作正常,我收到WebException。但是就在幾分鐘後,線程停止或崩潰。不知道巫婆是否正確...因此,如果線程被殺害,我實現了自動重啓......這非常難看,但它工作。

這個request.GetResponse()是怎麼回事?爲什麼即使異常被捕獲,它也會殺死線程?這很奇怪...