简体   繁体   English

使用异步等待C#Xamarin

[英]Using async await C# Xamarin

I have started using Xamarin recently and I am quite new to c#. 我最近开始使用Xamarin,对c#还是很陌生。 I want to create an asynchronous HTTP request, so I started using async and await with HttpWebRequest. 我想创建一个异步HTTP请求,因此我开始使用async并与HttpWebRequest等待。 But I don't get an asynchronous called, the UI is getting block. 但是我没有得到异步调用,UI越来越阻塞。 This is the code I'm testing. 这是我正在测试的代码。 I have two implementation the RequestCitas() should be asynchronous and the SRequestCitas() is synchronous, what is wrong?. 我有两个实现,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;
    }

}
}

You're getting response using an async method, but you're reading the stream using synchronous stream operations. 您正在使用async方法获得响应,但是您正在使用同步流操作读取流。 Try using streamReader.ReadAsync instead. 尝试改用streamReader.ReadAsync

Or, if you're feeling ambitious, you could try replacing your whole while loop altogether and use: 或者,如果您有雄心壮志,则可以尝试完全替换整个while循环并使用:

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. 附带说明一下, StreamReader实现了IDisposable ,使用完该实例后您将无法正确处置它。 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. 当您创建使用await关键字的方法时,对于我来说,编译器必须将其标记为async ,以允许使用关键字。 More over, you should follow the guidelines and end your method with the Async prefix 此外,您应遵循准则并以Async前缀结束方法

Your async method is reading synchronously from the from the StreamReader which is causing your UI to block. 您的async方法是从StreamReader同步读取,这导致您的UI阻塞。

Here's a async implementation using HttpClient : 这是使用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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM