【问题标题】:Downloading a string asynchronously, UI freezes briefly异步下载字符串,UI 短暂冻结
【发布时间】:2015-03-22 18:31:53
【问题描述】:

我正在编写一个 Xamarin.Forms 应用程序,但在使用异步发出请求时遇到了一些问题。当确实不应该发出网络请求时,它会暂时冻结。我做错了什么?

public RecipesView LatestRecipes
    (string searchTerm, long? fromTimestamp, int recordsPerPage, bool hasMoreRecords)
    {
        HttpClientHandler handler = new HttpClientHandler();
        handler.CookieContainer = Settings.cookies;

        string url = Settings.Default.baseUrl + "/Api/recipes/latest";
        Dictionary<string, string> queryString = new Dictionary<string, string> ();
        queryString.Add ("maxRecords", recordsPerPage.ToString());
        queryString.Add ("searchTerm", searchTerm);
        queryString.Add ("username", "");
        queryString.Add ("boardSlug", "");
        queryString.Add ("type", "json");

        string queryUrl = url + ToQueryString(queryString);

        string result = DownloadString (queryUrl, handler).Result;

        RecipesView view = JsonConvert.DeserializeObject<RecipesView> (result);
        hasMoreRecords = view.HasMoreRecords;

        foreach (RecipeModel model in view.Records) {
            model.OriginalImageWidth = model.ImageWidth;
            model.OriginalImageHeight = model.ImageHeight;
        }

        return view;

    }

    public async Task<string> DownloadString(string url, HttpClientHandler handler)
    {
        var httpClient = new HttpClient(handler); // Xamarin supports HttpClient!

        Task<string> contentsTask = httpClient.GetStringAsync(url); // async method!

        // await! control returns to the caller and the task continues to run on another thread
        string contents = await contentsTask;

        return contents; // Task<TResult> returns an object of type TResult, in this case int
    }

谢谢, 科林。

【问题讨论】:

  • 您对 DownloadString 的消费不是异步的。调用 .Result 正在等待任务完成。

标签: .net asynchronous xamarin xamarin.forms


【解决方案1】:

使用 async/await,您需要一直保持异步。因此,您也应该将 LatestRecipes 方法更改为异步。

public async Task<RecipesView> LatestRecipesAsync(string searchTerm, long? fromTimestamp, int recordsPerPage, bool hasMoreRecords)
{
// ... Your existing code ...
    string result = await DownloadString (queryUrl, handler);
// ... The rest of your code ...
}

此外,异步方法的推荐约定是在名称后加上 Async。

【讨论】:

  • 啊,我明白了,那么我需要返回多远?因此,对于父方法,我是否添加了一个等待,例如 RecipesView rv = await recipeService.LatestRecipes (searchTerm, fromTimestamp, maxRecords, hasMoreRecords);然后将 async 也添加到方法声明中?
  • 尽可能后退。在 WinForms/WPF 中,您在事件处理程序上执行 async void 并一直保持异步。我猜 Xamarin 也有类似的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 2015-06-07
相关资源
最近更新 更多