2014-06-24 53 views
1

我已經開始使用Xamarin最近,我很新的C#。我想創建一個異步HTTP請求,所以我開始使用異步並等待HttpWebRequest。但我沒有得到一個異步調用,用戶界面越來越封鎖。這是我正在測試的代碼。我有兩個實現RequestCitas()應該是異步的,並且SRequestCitas()是同步的,什麼是錯的?使用異步等待C#Xamarin

namespace mc 
{ 
[Activity (Label = "mc", MainLauncher = true, Theme="@android:style/Theme.Holo.Light")] 
public class MainActivity : Activity 
{ 

    List<Cita> citas; 
    CitaAdapter adapter; 

    protected override void OnCreate (Bundle savedInstanceState) 
    { 
     base.OnCreate (savedInstanceState); 
     SetContentView (Resource.Layout.Main); 


     citas = new List<Cita>(); 
     adapter = new CitaAdapter (this, citas); 
     ListView listView = FindViewById<ListView> (Resource.Id.main_citas); 
     listView.Adapter = adapter; 

     var c1 = new Cita (0, "ernesto", "De los Santos", "19/2/14", "19/2/14", "09:28", "10:45"); 
     var c2 = new Cita (1, "ernesto", "De los Santos", "19/2/14", "19/2/14", "09:28", "10:45"); 
     var c3 = new Cita (2, "ernesto", "De los Santos", "19/2/14", "19/2/14", "09:28", "10:45"); 
     var c4 = new Cita (3, "ernesto", "De los Santos", "19/2/14", "19/2/14", "09:28", "10:45"); 
     var c5 = new Cita (4, "ernesto", "De los Santos", "19/2/14", "19/2/14", "09:28", "10:45"); 

     citas.Add (c1); 
     citas.Add (c2); 
     citas.Add (c3); 
     citas.Add (c4); 
     citas.Add (c5); 

     Console.WriteLine ("Notificando al adaptador"); 
     adapter.NotifyDataSetChanged(); 

     string result; 

     FindViewById<Button> (Resource.Id.button1).Click += async (sender, e) => { 
      result = await RequestCitas(); 
     }; 
     FindViewById<Button> (Resource.Id.button2).Click += delegate { 
      result = SRequestCitas(); 
     }; 
    } 

    private async Task<string> RequestCitas() 
    { 

     // var url = "http://192.168.1.126:8081"; 
     var url = "http://192.168.1.124"; 
     //var method = "/citas/get"; 
     var method = ""; 

     var encoding = new UTF8Encoding(); 
     byte[] parametros = encoding.GetBytes ("usersID=97"); 

     var request = (HttpWebRequest)WebRequest.Create (url + method); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.ContentLength = parametros.Length; 

     var dataStream = request.GetRequestStream(); 
     dataStream.Write (parametros, 0, parametros.Length); 
     dataStream.Close(); 

     string str = ""; 

     Task<WebResponse> task = request.GetResponseAsync(); 

     WebResponse newResponse = await task; 

     var responseStream = newResponse.GetResponseStream(); 
     var streamReader = new StreamReader (responseStream, System.Text.Encoding.GetEncoding ("utf-8")); 
     char[] read = new Char[256]; 
     int count = streamReader.Read (read, 0, 256); 

     while (count > 0) { 
      str += new string (read, 0, count); 
      count = streamReader.Read (read, 0, 256); 
     } 
     responseStream.Close(); 

     return str; 
    } 


    private string SRequestCitas() 
    { 

     var url = "http://192.168.1.126:8081"; 
     var method = "/citas/get"; 

     var encoding = new UTF8Encoding(); 
     byte[] parametros = encoding.GetBytes ("usersID=97"); 

     var request = (HttpWebRequest)WebRequest.Create (url + method); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.ContentLength = parametros.Length; 

     var dataStream = request.GetRequestStream(); 
     dataStream.Write (parametros, 0, parametros.Length); 
     dataStream.Close(); 

     string str = ""; 

     HttpWebResponse newResponse = (HttpWebResponse)request.GetResponse(); 

     var responseStream = newResponse.GetResponseStream(); 
     var streamReader = new StreamReader (responseStream, System.Text.Encoding.GetEncoding ("utf-8")); 
     char[] read = new Char[256]; 
     int count = streamReader.Read (read, 0, 256); 

     while (count > 0) { 
      str += new string (read, 0, count); 
      count = streamReader.Read (read, 0, 256); 
     } 
     responseStream.Close(); 

     return str; 
    } 

} 
} 
+2

請問你的代碼編譯?你在非異步void方法內使用'await'。此外,它看起來像你的'while'循環是什麼阻止你的用戶界面,而不是等待的任務 –

回答

0

您使用async方法獲得響應,但您正在使用同步流操作讀取流。請嘗試使用streamReader.ReadAsync代替。

或者,如果你感覺雄心勃勃,你可以嘗試完全取代你的整個while循環及用途:

var str = await streamReader.ReadToEndAsync(); 

在一個側面說明,StreamReader實現IDisposable和你沒有正確處理實例的當你完成它。你可能會泄漏本地資源。

0

當您創建一個使用await關鍵字的方法時,必須將其標記爲async,以便編譯器允許使用該關鍵字。更結束了,你應該遵循的準則,並與異步前綴

async方法同步從從,這是造成你的用戶界面,以阻止StreamReader閱讀結束您的方法。

下面是使用HttpClient一個異步執行:

private async Task<string> RequestCitasAsync() 
{ 
    var url = "http://192.168.1.126:8081/citas/get"; 
    byte[] parametros = Encoding.UTF8.GetBytes("usersID=97"); 

    var httpClient = new HttpClient(); 
    var response = await httpClient.PostAsync(url, new ByteArrayContent(parametros)); 

    return await response.Content.ReadAsStringAsync(); 
}