【问题标题】:Ensure Device.BeginInvokeOnMainThread completes before next code executes in c#确保 Device.BeginInvokeOnMainThread 在 c# 中执行下一个代码之前完成
【发布时间】:2017-12-01 06:40:37
【问题描述】:

我在private async Task 的签名方法中包含以下代码。我的问题是ObservableCollection<Goods> goods = new ObservableCollection<Goods>(); 在下面的代码Device.BeginInvokeOnMainThread 完成之前被执行。在进入下一行之前,如何确保所有代码都已执行并正确获取值,即ObservableCollection<Goods> goods = new ObservableCollection<Goods>();

请注意,我在 Device... 之前使用了 await Task.Run(),但没有产生任何结果。

请帮忙。

Device.BeginInvokeOnMainThread(() =>
            {
                Location loc = new Location();
                GpsData = locService.GetLocation();
                a = GpsData.Latitude;
                b = GpsData.Longitude;

            });



        ObservableCollection<Goods> goods = new ObservableCollection<Goods>();

【问题讨论】:

  • 1. 你为什么要在主线程上获取地理位置?它不是 UI 操作,由平台/系统提供,您不需要它在代码的主线程上运行。 2.你需要await的唯一代码行是locService.GetLocation();,如果这个``GetLocation`方法不是异步的,你甚至不需要让你的代码异步。

标签: c# xamarin


【解决方案1】:

用这样的方法提取GPS位置检索码:

async Task GetGpsData()
{
    var tcs = new TaskCompletionSource<bool>();

    Device.BeginInvokeOnMainThread(() => {
        try
        {
            Location loc = new Location();
            GpsData = locService.GetLocation();
            a = GpsData.Latitude;
            b = GpsData.Longitude;
            tcs.SetResult(true);
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    });

    return tcs.Task;
}

然后按如下方式使用:

await GetGpsData();
ObservableCollection<Goods> goods = new ObservableCollection<Goods>();

编辑

GetGpsData() 是一个私有方法,使其成为async 应该没有问题。然而它基本上意味着调用者代码也必须是async。如果这不可能,请执行以下操作:

GetGpsData().Wait();
ObservableCollection<Goods> goods = new ObservableCollection<Goods>();

【讨论】:

  • 我们不能return tcs.Task;。所以我只是省略并现在测试
  • 请参阅答案中的编辑。您不必更改现有代码中的方法签名。请注意,GetGpsData() 是一个新的辅助方法,没有其他代码依赖它。因此,使 GetGpsData() 异步应该没有问题。
猜你喜欢
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 2016-09-12
  • 2020-04-29
  • 2018-05-20
  • 1970-01-01
相关资源
最近更新 更多