2013-08-13 47 views
6

Aşağıdaki kodu uyumsuz ve beklemede tutmam gerekiyor.Sıradan WebRequest'i nasıl belirsiz ve beklemek gerekir?

Web sunucusundan çok fazla veri almam gerekiyor ve bu veri, uygulamada xaml sayfasını doldurmak için kullanılacaktır.

Bu yüzden, bilinmek için DefLogin() yöntemine ihtiyacım var.

Mümkün mü?

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  
     } 
    } 

Ben StackOverflow'daki bu soruyu gördü: Converting ordinary Http Post web request with Async and Await ama düzgün cevap anlayamadık.

Lütfen herhangi bir kişi yardım edebilir mi? Gerçekten minnettar olurum! Sonra (gerekirse) vb Stream.Write, Stream.Flush,

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

ve yapılacak aynı WebRequest.GetResponse için ve:

cevap

13

Böyle küçücük uzatma yöntemleri bir sürü yapım convert APM to TAP için TaskFactory.FromAsync kullanabilirsiniz Herhangi bir geri arama olmadan async ve await kullanarak gerçek mantığınızı yazabilirsiniz:

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

Harika cevap. Bu gerçekten daha fazla kredi hak ediyor. Benim deneyimden, uzantı yöntemleri "Görev .Factory.FromAsync (etc ...)" gibi görünmelidir, aksi takdirde "çağrı belirsiz" hata olarak çalışır. Ayrıca using() öğelerini atmayın: EndGet ___() önce akışınızın kapalı olduğundan emin olmak için çok önemlidir. –