当前位置: 动力学知识库 > 问答 > 编程问答 >

android - Using async await C# Xamairn

问题描述:

I have started using Xamarin recently and I am quite new to c#. I want to create an asynchronous HTTP request, so I started using async and await with HttpWebRequest. But I don't get an asynchronous called, the UI is getting block. This is the code I'm testing. I have two implementation the RequestCitas() should be asynchronous and the SRequestCitas() is synchronous, what is wrong?. THANKS.

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;

}

}

}

网友答案:

You're getting response using an async method, but you're reading the stream using synchronous stream operations. Try using streamReader.ReadAsync instead.

Or, if you're feeling ambitious, you could try replacing your whole while loop altogether and use:

var str = await streamReader.ReadToEndAsync();

On a side note, StreamReader implements IDisposable and you're not properly disposing of the instance when you're done with it. You could be leaking native resources.

网友答案:

When you create a method which uses the await keyword, it has to me be marked as async for the compiler to allow the use of the keyword. More over, you should follow the guidelines and end your method with the Async prefix

Your async method is reading synchronously from the from the StreamReader which is causing your UI to block.

Here's a async implementation using 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();
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: