等待句柄和Xamarin Forms

3

我目前正在使用Xamarin的免费试用版开发一个概念验证应用,但遇到了一个有趣的小问题...这是我在可移植类库中使用的代码:

using System;
using System.Net;
using Newtonsoft.Json;

namespace poc
{
    public class CurrentWeatherInformation
    {

        public string WeatherText { get; set; }

        public CurrentWeatherInformation (string cityName)
        {
            // api.openweathermap.org/data/2.5/weather?q=Leeds
            var request = (HttpWebRequest)WebRequest.Create(string.Format("http://api.openweathermap.org/data/2.5/weather?q={0}", cityName));
            request.ContentType = "application/json";
            request.Method = "GET";
            object state = request;

            var ar = request.BeginGetResponse (WeatherCallbackMethod, state);
            var waitHandle = ar.AsyncWaitHandle as System.Threading.ManualResetEvent;

            waitHandle.WaitOne();
        }

        public void WeatherCallbackMethod(IAsyncResult ar)
        {
            object state = ar.AsyncState;
            var request = state as HttpWebRequest;
            var response = request.EndGetResponse(ar);
            var data = new System.IO.StreamReader (response.GetResponseStream ()).ReadToEnd ();
            this.WeatherText = data;
        }

    }
}

基本上,我只想调用一个Web服务并获得响应,但是我注意到使用Xamarin时无法使用老旧的GetResponse()方法来实现这一点,而必须使用BeginGetResponse()EndGetResponse(),并采用旧的IAsyncResult模式。问题出现了。
无论如何,我的问题是,在等待waitHandle后,紧随其后的代码在回调代码之前执行,我不知道为什么。这正是我们使用等待句柄的原因!有谁能发现我肯定会犯的一个简单错误吗?
1个回答

2
在Windows Phone上,你被迫使用异步API。当你试图在主线程同步等待异步方法的结果时,可能会陷入无限循环中。在执行昂贵的操作时,请使用asyncawait。这是进行异步工作的常见模式。
请参阅一些教程: https://visualstudiomagazine.com/articles/2013/10/01/asynchronous-operations-with-xamarin.aspx http://developer.xamarin.com/recipes/android/web_services/consuming_services/call_a_rest_web_service/ How to implement Android callbacks in C# using async/await with Xamarin or Dot42? https://github.com/conceptdev/xamarin-forms-samples/blob/master/HttpClient/HttpClientDemo/GeoNamesWebService.cs

问题在于(我已相应修改了我的问题),我向您展示的代码位于可移植类库中,这意味着GetResponseAsync等方法不可用。实际上,我唯一的选择是使用BeginGetResponse和EndGetResponse方法... - Martin Milan
1
不,你有更多的选项。你可以使用System.Net.Http.HttpClientasync/await。这是在 Xamarin 中使用 Web 服务的常见方式,如教程中所示。 - Wosi
似乎我们不能在Xamarin中使用System.Net.Http,因为它的Nuget实现还不够完善(<3)。尝试切换到Visual Studio,但现在项目无法编译。我开始对此感到烦恼了,哈哈... - Martin Milan
你说 System.Net.Http “不够成熟”是什么意思?它已经很稳定了,许多人都在他们的生产应用程序中使用它。 - Wosi
当我尝试获取nuget包时,我收到一个警告,说Xamarin的nuget客户端不够高,我认为是2.8.3,无法下载该包。它声称需要3+。尽管如此,似乎它已经成功地下载了该包... - Martin Milan
1
对不起,请使用 Microsoft.Net.Http。这里解释了它与 System.Net.Http 的区别:https://dev59.com/SF0Z5IYBdhLWcg3wzC5W - Wosi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接