【问题标题】:Xamarin Android app - Problems adding async/await to an API call to improve performanceXamarin Android 应用程序 - 向 API 调用添加异步/等待以提高性能时出现问题
【发布时间】:2017-10-18 02:03:41
【问题描述】:

我发现我的 Xamarin Android 应用程序运行缓慢,因此我添加了一些异步/等待代码以提高性能。我想从 UI 线程中排除我的 API 调用。我认为这将是使用 async/await 的绝佳机会。因此,我将 async 添加到函数的签名中,并将 Task 包装在我的返回值类型周围。然后我用“await client.ExecuteTaskAsync”更新了 RestSharp GET 调用。完成此操作后,我发现我需要更新对 GetCustInfo 函数的调用。我只需将 .Result 添加到通话结束时,它就没有显示错误。问题是它挂在对 GetCustInfo 的调用上并且不起作用。

我在这里做错了什么?

    public async Task<List<CustInfo>> GetCustInfo(string strBranchNumber, string dblCurrentXCoordinate, string dblCurrentYCoordinate)
    {
        if (this.strBearerToken == string.Empty)
        {
            throw new ArgumentException("No Bearer Token Found");
        }

        try
        {
            var restUrl = this.strCustomerInfoAPIURL;
            var uri = new Uri(string.Format(restUrl, string.Empty));

            var client = new RestClient(uri);
            var request = new RestRequest(Method.GET);
            request.AddHeader("Authorization", "bearer " + this.strBearerToken);
            request.AddParameter("intBranchNumber", strBranchNumber);
            request.AddParameter("intZipCode", this.strZipCode);
            request.AddParameter("intCustomerType", this.strCustomerType);
            request.AddParameter("intMinTotalAmount", this.strMinRevenue);
            request.AddParameter("dblCurrentXCoordinate", dblCurrentXCoordinate);
            request.AddParameter("dblCurrentYCoordinate", dblCurrentYCoordinate);
            request.AddParameter("bolGetLocation", true);

            var response = await client.ExecuteTaskAsync(request);                
            return JsonConvert.DeserializeObject<List<CustInfo>>(response.Content).OrderBy(x => x.ApproxDistance).ToList();
        }
        catch (Exception ex)
        {
            return null;
        }
    }

所以发生的情况是,当我从 OnCreate 调用 async/await 函数时,它会在我尝试调用 customer.GetCustomerInfo() 时停止。

    protected override void OnCreate(Bundle bundle)
    {
      ....

            this.tableItems = customer.GetCustInfo(
                "xxxxxxx",
                this.currentLocation.Latitude.ToString(),
                this.currentLocation.Longitude.ToString()).Result;
             this.listView.Adapter = new ListOfLocationAdapter(this, this.tableItems);

    }

【问题讨论】:

  • OnCreate 本身位于您正在输入的操作的 UI 线程上,而不是异步的,并且您没有等待对 GetCustInfo 的调用。所以它的行为就像一个阻塞调用。在 UI 生命周期中使用不同的事件来触发它,并使用 await 语法调用它。
  • 你能举例说明你的意思吗? UI 生命周期中的所有事件不都是 UI 线程的一部分吗?
  • 我做了一些研究,发现我应该在生命周期内的 OnStart 调用中添加对 custinfo 的调用。这是工作。感谢您的提示!

标签: c# android-asynctask xamarin.android


【解决方案1】:

把调用改成

this.tableItems = await customer.GetCustInfo(..

让我们知道.. 在下一行中,您正在使用未等待调用的结果,它显然会挂起,崩溃:

this.listView.Adapter = new ListOfLocationAdapter(this, **this.tableItems**); //this.tableItems is just empty

【讨论】:

  • 只需使用您的 OnCreate 的全部内容创建一个异步函数并在没有等待的情况下调用它,现在这样可以加快速度并执行您想要的操作。
猜你喜欢
  • 1970-01-01
  • 2021-06-18
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
相关资源
最近更新 更多