2012-06-08 13 views
6

Veriyi uzaktaki bir sunucuya/sunucudan sürekli olarak senkronize eden bir arka plan çalışan iş parçacığım var. Uygulamayı ilk çalıştırdığımda her şey iyi çalışıyor. Her 30 saniyede bir web isteği yapar ve veri başarıyla döner.HTTPWebRequest & Bir süre sonra, 400 (Hatalı İstek) başlıyor

Simülatörün uzun bir süre çalışmasını bırakırsam, sonuçta (400) Hatalı İstek ile istek başarısız olur. Ve sonraki tüm istekler aynı şeyi yapar. Uygulamayı öldürüp yeniden başlatırsam ... her şey yolunda.

Herhangi bir fikri olan var mı? Kod aşağıda.

public RestResponse<T> Execute<T>(RestRequest request) { 
    var restResponse = new RestResponse<T>(); 
    var serializer = new JavaScriptSerializer(); 
    var urlPath = baseUrl + "/" + request.Resource; 
    Console.WriteLine("Requesting: " + urlPath); 
    var httpRequest = (HttpWebRequest)HttpWebRequest.Create(new Uri(urlPath)); 

    httpRequest.Headers = request.Headers; 
    foreach (string key in clientHeaders.Keys) 
     httpRequest.Headers.Add(key, clientHeaders[key]); 
    httpRequest.Headers.Add("Accept-Encoding", "gzip,deflate"); 

    Authenticator.Authenticate(httpRequest); 
    httpRequest.Method = request.Method.ToString();  
    HttpWebResponse httpResponse = null; 
    try { 
     if ((request.Method == Method.POST) && (!request.IsJsonPost)) 
      SetPostData(httpRequest, request); 

     if ((request.Method == Method.POST) && (request.IsJsonPost)){ 
      SetJsonPostData(httpRequest, request); 
     } 

     httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 
     var reader = new StreamReader(GetStreamForResponse(httpResponse)); 
     var responseString = reader.ReadToEnd(); 
     Console.WriteLine(responseString); 
     reader.Close(); 
     restResponse.StatusCode = httpResponse.StatusCode; 
     restResponse.Headers = httpResponse.Headers; 
     restResponse.Data = serializer.Deserialize<T>(responseString); 
     restResponse.ResponseStatus = ResponseStatus.Completed; 
     httpResponse.Close(); 
    } catch (WebException e) { 
     restResponse.ResponseStatus = ResponseStatus.Error; 
     restResponse.ErrorMessage = e.Message; 
     restResponse.ErrorException = e; 
     var webResponse = (HttpWebResponse)e.Response; 
     if (webResponse != null) { 
      restResponse.StatusCode = webResponse.StatusCode; 
      restResponse.Headers = webResponse.Headers; 
     } 
     if (restResponse.StatusCode != HttpStatusCode.NotModified) 
      Console.WriteLine("An exception occured:\r\n " + request.Resource + "\r\n" + e + "\r\n"); 
    } catch (Exception ex) { 
     restResponse.ResponseStatus = ResponseStatus.Error; 
     restResponse.ErrorMessage = ex.Message; 
     restResponse.ErrorException = ex; 
    } 

    if (httpResponse != null) 
     httpResponse.Close(); 

    return restResponse; 
} 

Bu hat üzerinde başarısız:

httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 

Yığın İzleme:

System.Net.WebException: The remote server returned an error: (400) Bad Request. 
    at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x002f2] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1477 
    at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1300 

isteği asla uzak sunucuya oluyor.

+0

** 400 ** sunucudan geliyor. Bir sniffer (örneğin, wireshark) çalıştırabilir ve bu durumda ne iletildiğini bulursanız (ve bundan önce aldığınız normal yanıtla karşılaştırırsanız) yardımcı olacaktır. – poupou

+0

Bu garip şey, sunucudan gelmiyor. IIS, istek gelmiyor asla görmez. –

+0

Çok garip - ama güzel bir ipucu! – poupou

cevap

2

sorun clientHeaders koleksiyonunda oldu. Bu RESTClient sınıfı, uygulama ömrü boyunca bir kez başlatılır. Başlıkları üst üste ekledim ve önce onları temizlemedim. Bir süre sonra, başlıklar çok büyük oldu ve kötü bir talep yapıldı.

+1

Verilen kodu bakarak bunu anlamak kolay değildi :) –

0

Bağlantılarınız bittiğini varsayalım. Bunları artırmak için deneyebilirsiniz:

<configuration> <system.net> <connectionManagement> <add address="*" maxconnection="65535" /> </connectionManagement> </system.net> </configuration>

+0

Bağlantıları artırmak için yine de deneyebilirsiniz. – NickD

+0

MonoTouch'da bunu nasıl yaparım? –

+0

System.Net.ServicePointManager.DefaultConnectionLimit = 65535; – NickD