2012-12-21 8 views
5

Sto lavorando con un'applicazione WPF .net 4.0. Ho una barra di ricerca. Per ogni token di ricerca devo eseguire 8 richieste http su 8 URL separati per ottenere risultati di ricerca. Invio 8 richieste al server dopo 400 millisecondi dopo che l'utente ha smesso di digitare nella barra di ricerca. La ricerca di risultati da 6 a 7 per i token di ricerca si presenta molto bene. Ma dopo questo improvvisamente HttpWebRequest smette di funzionare silenziosamente. Nessuna eccezione è stata lanciata, nessuna risposta è stata ricevuta. Sto lavorando con Windows 7, ho disabilitato anche il firewall. Non so dove sono perse le successive richieste http.HttpWebRequest smette di funzionare all'improvviso, nessuna risposta ricevuta dopo poche richieste

Qualcuno può mostrarmi luci per risolvere questo problema?

Di seguito è riportato il mio codice per la chiamata HttpWebRequest.

public static void SendReq(string url) 
{ 
    // Create a new HttpWebRequest object. 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 

    request.ContentType = "application/x-www-form-urlencoded"; 
    request.Proxy = new WebProxy("192.168.1.1", 8000); 

    // Set the Method property to 'POST' to post data to the URI. 
    request.Method = "POST"; 

    // start the asynchronous operation 
    request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request); 

} 

private static void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
{ 
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

    // End the operation 
    Stream postStream = request.EndGetRequestStream(asynchronousResult); 

    string postData = this.PostData; 

    // Convert the string into a byte array. 
    byte[] byteArray = Encoding.UTF8.GetBytes(postData); 

    // Write to the request stream. 
    postStream.Write(byteArray, 0, byteArray.Length); 
    postStream.Close(); 

    // Start the asynchronous operation to get the response 
    request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request); 
} 

private static void GetResponseCallback(IAsyncResult asynchronousResult) 
{ 
    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

    // End the operation 
    using(HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult)) 
    { 
     using(Stream streamResponse = response.GetResponseStream()) 
     { 
      using(StreamReader streamRead = new StreamReader(streamResponse)) 
      { 
       string responseString = streamRead.ReadToEnd(); 
       Debug.WriteLine(responseString); 
      } 
     } 
    } 
} 
+1

Quanto sei certo che non vengano lanciate eccezioni per le altre richieste? Le tue chiamate 'Close' non sono in istruzioni' using', il che significa che se ci sono eccezioni, lascerai aperte le connessioni di risposta, che potrebbero deadlock in seguito richieste ... –

+0

Non viene generata alcuna eccezione. L'applicazione è completamente silenziosa. Nessuna risposta ricevuta GetResponseCallback non viene mai chiamato dopo 6 o 7 richieste. Ho aggiornato il codice. Aggiunto * usando * ma ancora lo stesso problema. – Somnath

+0

Hai guardato cosa sta succedendo a livello di rete con qualcosa come Wireshark? –

risposta

2

Tutto quello che posso vedere è che in GetRequestStreamCallback si dovrebbe sostituire

postStream.Write(byteArray, 0, postData.Length); 

da

postStream.Write(byteArray, 0, byteArray.Length); 

dal momento che questi lunghezza non sono necessariamente uguali.

+0

Grazie Clemens, suona bene. Proprio ora ho fatto i cambiamenti nel mio codice. Anche non risolve questo problema di errore silenzioso di HttpWebRequest. – Somnath

0

@Somnath Non sono sicuro di aver trovato questa risposta, ma se qualcun altro si imbatte in questo post con lo stesso problema che Somnath e io stavamo avendo.

Tutti noi proviamo a fare la nostra due diligence nel mantenere la memoria pulita e chiara, ma con i flussi salveremo sempre problemi inspiegabili se ci assicureremo di svuotare il flusso prima di chiuderlo.

sostituire questo:

postStream.Write(byteArray, 0, byteArray.Length); 
postStream.Close(); 

con questo:

postStream.Write(byteArray, 0, byteArray.Length); 
postStream.Flush(); 
postStream.Close(); 
+0

Ciao Jdunn, Proprio ora ho provato il tuo suggerimento ma non ci sono riuscito. Ho lavato e chiuso tutti i flussi. In modo che non ci siano perdite di memoria nel mio codice. Ancora senza fortuna. Tieni presente che quando continuo a digitare nella casella di ricerca che sto inviando potrebbero essere richieste prima che alcune richieste tornino con risposta. Sto solo ignorando le risposte precedenti. Ora suppongo di dover fare qualcosa con l'annullamento della richiesta. A cosa stai pensando? Qualche ipotesi ...! – Somnath

-1

Ho seguito tutte suggerimento fornire da tutti voi, ma non riusciva a smettere il fallimento silenzioso di richiesta HTTP. Ma ho trovato una soluzione alternativa. Perfino io stesso non sono riuscito a raggiungere una conclusione definitiva fino ad ora.

Ma il mio workaround sta funzionando bene come ora senza alcun errore.

In SendReq (stringa URL) funzione ho aggiunto le seguenti righe di codice

System.Net.ServicePointManager.DefaultConnectionLimit = 100; // Just selected a random number for testing greater than 2 
System.Net.ServicePointManager.SetTcpKeepAlive(true, 30, 30); // 30 is based on my server i'm hitting 
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

request.KeepAlive = true; 
4

Penso di essere molto in ritardo, ma ho ancora voglia di rispondere alla tua domanda, può essere può essere utile agli altri. Per impostazione predefinita, le richieste HTTP effettuate sono richieste HTTP 1.1. E la richiesta HTTP 1.1 di default ha la connessione Keep-Alive. quindi quando fai troppe richieste allo stesso server .net framework fai solo x no. di richiesta

è necessario chiudere tutte le vostre risposte da response.Close()

è anche possibile specificare il numero di richieste simultanee si può fare.

ServicePointManager.DefaultConnectionLimit = 20; 

Si noti che è necessario impostare DefaultConnectionLimit prima che la prima richiesta effettuata.puoi trovare ulteriori informazioni here on msdn.