2014-10-27 2 views
46

Ich habe versucht herauszufinden, wie man den Inhalt eines httpclient Anrufs liest, und ich kann nicht scheinen, es zu bekommen. Der Antwortzustand, den ich bekomme, ist 200, aber ich kann nicht herausfinden, wie man zum tatsächlichen JSON kommt, der zurückgebracht wird, der alles ist, was ich brauche! Wie man Inhaltskörper von einem httpclient Anruf erhält?

Das folgende ist mein Code:

 async Task<string> GetResponseString(string text) 
    { 
     var httpClient = new HttpClient(); 

     var parameters = new Dictionary<string, string>(); 
     parameters["text"] = text; 
     Task<HttpResponseMessage> response = httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)); 

     return await response.Result.Content.ReadAsStringAsync(); 
    } 

Und ich bin immer es sie von einer Methode nur aufrufen:

Task<string> result = GetResponseString(text); 

und das ist, was ich

response Id = 89, Status = RanToCompletion, Method = "{null}", Result = "StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n Connection: keep-alive\r\n Date: Mon, 27 Oct 2014 21:56:43 GMT\r\n ETag: \"5a266b16b9dccea99d3e76bf8c1253e0\"\r\n Server: nginx/0.7.65\r\n Content-Length: 125\r\n Content-Type: application/json\r\n}" System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>

bekommen

Aktualisierung: Dies ist mein aktueller Code pro Nathans Antwort unter

  async Task<string> GetResponseString(string text) 
    { 
     var httpClient = new HttpClient(); 

     var parameters = new Dictionary<string, string>(); 
     parameters["text"] = text; 

     var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)); 
     var contents = await response.Content.ReadAsStringAsync(); 

     return contents; 
    } 

Und ich nenne es von dieser Methode ....

string AnalyzeSingle(string text) 
    { 
     try 
     { 
      Task<string> result = GetResponseString(text); 
      var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result); 

      if (Convert.ToInt16(model.pos) == 1) 
      { 
       _numRetries = 0; 
       return "positive"; 
      } 

      if (Convert.ToInt16(model.neg) == 1) 
      { 
       _numRetries = 0; 
       return "negative"; 
      } 

      if (Convert.ToInt16(model.mid) == 1) 
      { 
       _numRetries = 0; 
       return "neutral"; 
      } 

      return ""; 

     } 
     catch (Exception e) 
     { 
      if (_numRetries > 3) 
      { 
       LogThis(string.Format("Exception caught [{0}] .... skipping", e.Message)); 
       _numRetries = 0; 
       return ""; 
      } 
      _numRetries++; 
      return AnalyzeSingle(text); 
     } 
    } 

Und es läuft weiter für immer, trifft es die Linie var model = JsonConvert.DeserializeObject<SentimentJsonModel>(result.Result); Einmal, und es geht weiter ohne Unterbrechung an einem anderen Haltepunkt.

Wenn ich die Ausführung anhalten, sagen Sie

Id = Kann nicht Ausdruck auswerten, da der Code der aktuellen Methode optimiert., Status = Ausdruck kann nicht beurteilen, da der Code der aktuellen Methode optimiert ist., Verfahren = Ausdruck kann nicht ausgewertet werden, da der Code der aktuellen Methode optimiert ist., Ergebnis = Ausdruck kann nicht ausgewertet werden, da der Code der aktuellen Methode optimiert ist.

.. I Ausführung fortsetzen, aber es läuft nur für immer. Nicht sicher, was das Problem ist

+0

Wo und wie ist _numRetries definiert? –

+0

Es ist im Bereich der Klasse und wird mit einer 0 im Konstruktor initialisiert. AnalyzeSingle() ist der einzige Ort, an dem ich es verwende. –

+0

Laufen Sie im Debug-Modus? Das optimierte Problem liegt möglicherweise daran, dass Sie im Freigabemodus ausgeführt werden. –

Antwort

80

Die Art, wie Sie verwenden, erwarten/async ist bestenfalls schlecht, und es macht es schwer zu folgen. Sie mischen await mit Task'1.Result, was nur verwirrend ist. Es sieht jedoch so aus, als würden Sie sich ein endgültiges Aufgabenergebnis ansehen und nicht den Inhalt.

Ich habe Ihre Funktion und Funktionsaufruf neu geschrieben, die das Problem beheben sollen:

async Task<string> GetResponseString(string text) 
{ 
    var httpClient = new HttpClient(); 

    var parameters = new Dictionary<string, string>(); 
    parameters["text"] = text; 

    var response = await httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)); 
    var contents = await response.Content.ReadAsStringAsync(); 

    return contents; 
} 

Und Ihren letzten Funktionsaufruf:

Task<string> result = GetResponseString(text); 
var finalResult = result.Result; 

Oder noch besser:

var finalResult = await GetResponseString(text); 
+0

Danke !! Ich habe versucht, zu bekommen, wie async/warten in den letzten paar Stunden funktioniert (MSDN + stackoverflow), aber ich habe es offensichtlich noch nicht vollständig verstanden. Gibt es irgendwelche Ressourcen, die Sie vorschlagen würden? –

+0

Mach einfach weiter damit herum und du wirst schließlich den Dreh raus bekommen. Es ist ein großes Konzept, um alles auf einmal zu erfassen. –

+0

Ich habe immer noch Probleme. Ich habe mein Problem auf dem ursprünglichen Post aktualisiert. Das Problem kann sein, dass ich synchrone Ausführung bin, aber ich bin nicht sicher, wie dieses Problem zu lösen ist. –

32

Wenn Sie nicht async verwenden möchten, können Sie .Result hinzufügen der Code, der synchron ausgeführt wird:

private string GetResponseString(string text) 
    { 
     var httpClient = new HttpClient(); 

     var parameters = new Dictionary<string, string>(); 
     parameters["text"] = text; 

     var response = httpClient.PostAsync(BaseUri, new FormUrlEncodedContent(parameters)).Result; 
     var contents = response.Content.ReadAsStringAsync().Result; 

     return contents; 
    } 
+0

Dieser Code kann zu einem Deadlock führen, wenn er von einem UI-Thread aufgerufen wird. –

+0

@nbushnell Hinzufügen von .Result zu Ihrem PostAsync macht es nicht async – Mike