Using async await C# Xamarin

本文关键字:Xamarin await async Using | 更新日期: 2023-09-27 18:10:03

我最近开始使用Xamarin,我对c#还是个新手。我想创建一个异步HTTP请求,所以我开始使用async和等待HttpWebRequest。但我没有得到一个异步调用,UI正在获取block。这是我正在测试的代码。我有两个实现,RequestCitas()应该是异步的,而SRequestCitas()是同步的,这是什么问题?

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

Using async await C# Xamarin

您使用async方法获得响应,但是您使用同步流操作读取流。试试用streamReader.ReadAsync代替。

或者,如果你有野心,你可以尝试替换整个while循环,并使用:

var str = await streamReader.ReadToEndAsync();

顺便说一句,StreamReader实现了IDisposable,当您完成它时,您没有正确地处理实例。您可能会泄漏本机资源。

当您创建使用await关键字的方法时,我必须将其标记为async,以便编译器允许使用该关键字。此外,您应该遵循指导原则,并以Async前缀

结束您的方法

你的async方法正在同步地从StreamReader读取,这导致你的UI阻塞。

这是一个使用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();
}