2013-08-13 5 views
6

Ich muss den folgenden Code async und erwarteter machen.Wie man gewöhnliches WebRequest async und erwartbar macht?

Ich muss eine Menge Daten vom Webserver erhalten, und dann werden diese Daten verwendet, um die XAML-Seite in meiner Anwendung zu füllen.

So brauche ich die DefLogin() -Methode zu erwarten.

Ist es möglich?

public void DefLogin() 
    { 
     postData = "My Data To Post"; 
     var url = new Uri("Url To Post to", UriKind.Absolute); 
     webRequest = WebRequest.Create(url); 
     webRequest.Method = "POST"; 
     webRequest.ContentType = "text/xml"; 
     webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest); 
    } 

    public void GetRequestStreamCallback(IAsyncResult asynchronousResult) 
    { 
     webRequest = (HttpWebRequest)asynchronousResult.AsyncState; 
     Stream postStream = webRequest.EndGetRequestStream(asynchronousResult); 
     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
     postStream.Write(byteArray, 0, byteArray.Length); 
     postStream.Close(); 
     Debug.WriteLine("Start BEGINGetResponse"); 
     webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest); 
    } 

    public void GetResponseCallback(IAsyncResult asynchronousResult) 
    { 
     try 
     { 
      HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState; 
      HttpWebResponse response; 
      response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult); 
      Stream streamResponse = response.GetResponseStream(); 
      StreamReader streamReader = new StreamReader(streamResponse); 
      string Response = streamReader.ReadToEnd(); 
      streamResponse.Close(); 
      streamReader.Close(); 
      response.Close(); 
      if (Response == "") 
      { 
       //show some error msg to the user   
       Debug.WriteLine("ERROR"); 

      } 
      else 
      { 
       //Your response will be available in "Response" 
       Debug.WriteLine(Response); 
      } 
     } 
     catch (WebException) 
     { 
      //error  
     } 
    } 

sah ich diese Frage auf Stackoverflow: Converting ordinary Http Post web request with Async and Await, aber ich konnte die Antwort nicht richtig verstehen.

Bitte kann jemand helfen? Ich wäre wirklich dankbar!

Antwort

13

Sie können TaskFactory.FromAsync zu convert APM to TAP, verwenden viele kleine Erweiterungsmethoden wie diese machen:

public static Task<Stream> GetRequestStreamAsync(this WebRequest request) 
{ 
    return TaskFactory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null); 
} 

und das gleiche für WebRequest.GetResponse und (falls erforderlich) Stream.Write, Stream.Flush usw.

Dann Sie können Ihre tatsächliche Logik mit async und await ohne Rückrufe schreiben:

public async Task DefLoginAsync() 
{ 
    postData = "My Data To Post"; 
    var url = new Uri("Url To Post to", UriKind.Absolute); 
    webRequest = WebRequest.Create(url); 
    webRequest.Method = "POST"; 
    webRequest.ContentType = "text/xml"; 
    using (Stream postStream = await webRequest.GetRequestStreamAsync()) 
    { 
     byte[] byteArray = Encoding.UTF8.GetBytes(postData); 
     await postStream.WriteAsync(byteArray, 0, byteArray.Length); 
     await postStream.FlushAsync(); 
    } 
    try 
    { 
     string Response; 
     using (var response = (HttpWebResponse)await webRequest.GetResponseAsync()); 
     using (Stream streamResponse = response.GetResponseStream()) 
     using (StreamReader streamReader = new StreamReader(streamResponse)) 
     { 
      Response = await streamReader.ReadToEndAsync(); 
     } 
     if (Response == "") 
     { 
      //show some error msg to the user   
      Debug.WriteLine("ERROR"); 

     } 
     else 
     { 
      //Your response will be available in "Response" 
      Debug.WriteLine(Response); 
     } 
    } 
    catch (WebException) 
    { 
     //error  
    } 
} 
+2

Erstaunliche Antwort. Dieser verdient wirklich mehr Kredit. Aus meiner Erfahrung sollten die Erweiterungsmethoden aussehen wie "return Task .Factory.FromAsync (etc ...)", sonst wird der Fehler "Der Aufruf ist mehrdeutig" angezeigt. Lassen Sie auch die using() 's nicht aus: Sie sind sehr wichtig, um sicherzustellen, dass Ihr Stream vor EndGet geschlossen ist ___(). –