【问题标题】:Async operation does not stop at await command异步操作不会在 await 命令处停止
【发布时间】:2018-01-05 10:18:31
【问题描述】:

我想在 Xamarin CrossPlatform 应用程序上获取我的 gps 坐标,但我遇到了问题。

我有这个代码:

public MapPage()
    {
        SearchPosition();
        map = new Map
        {
            IsShowingUser = true,
            HeightRequest = 100,
            WidthRequest = 960,
            VerticalOptions = LayoutOptions.FillAndExpand
        };

        map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(position.Latitude, position.Longitude), Distance.FromMiles(0.3)));
        ...
        ...
    }

    private async void SearchPosition()
    {
       position = await getPosition();
    }

    async Task<Plugin.Geolocator.Abstractions.Position> getPosition()
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;

        Plugin.Geolocator.Abstractions.Position position = await locator.GetPositionAsync(TimeSpan.FromSeconds(5));

        return position;
    }

我想要的只是等待 gps 坐标,但它会继续并在我获得 gps 坐标之前转到“MoveToRegien”。我不明白为什么,有人可以帮助我吗?谢谢!

【问题讨论】:

  • 异步 void 就像一团火,一劳永逸。像这样,您无需等待 SearchPosition 方法完成。
  • 我该如何等待呢?
  • @mnemonic 我看到了帖子,但它并没有解决问题。有什么想法吗?
  • @Imrik 如果你想要/需要一些 async/await 用法的例子,你也可以看看我的这个答案:stackoverflow.com/a/48127799/2814072

标签: c# android asynchronous xamarin gps


【解决方案1】:

在您的 SearchPosition 方法中返回 void 而不是 Task 是否有任何特殊原因?

这可能是你的问题,所以把它改成:

async Task SearchPosition()

我实际上会改变它以返回一个位置:

async Task<Plugin.Geolocator.Abstractions.Position> SearchPosition() => await GetPosition();

另一个问题是,你真的需要用SearchPosition() 方法包装GetPosition() 方法,除了调用第一个方法之外什么都不做?好像一团糟。

您的代码很难看,您没有遵循命名约定,您的代码有一半看起来像 Java,而另一半看起来像 C#。请在编写代码时尊重语言和自己,熟悉naming conventions 并关注他们。

编辑:
我想我现在看到了你真正的问题。您正试图在构造函数中获得一个位置,因此您不需要等待异步 SearchPosition() 方法。

例如,如果您的 MainPage 实际上源自 ContentPage,我建议将您的 GPS 相关逻辑移至 OnAppearing 方法。这是一个例子:

public class MainPage : ContentPage
{
    ...
    public MainPage()
    {
        map = new Map
        {
            IsShowingUser = true,
            HeightRequest = 100,
            WidthRequest = 960,
            VerticalOptions = LayoutOptions.FillAndExpand
        };
    }

    protected async override void OnAppearing()
    {
        position = await GetPosition();

        map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(position.Latitude, position.Longitude), Distance.FromMiles(0.3)));
    }

    async Task<Plugin.Geolocator.Abstractions.Position> GetPosition()
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;

        Plugin.Geolocator.Abstractions.Position position = await locator.GetPositionAsync(TimeSpan.FromSeconds(5));

        return position;
    }
}

【讨论】:

  • 感谢您的建议。它不起作用,它的位置变量仍然有空值。
  • 更新了我的答案。
  • 我更新了代码,并在 OnAppearing 方法处设置了断点,它不会在任何代码行处停止。它仍然在位置变量处具有空值。还有什么想法吗?非常感谢! :)
  • 哦,我修好了,我的错。但知道我有这个异常:未处理的异常:Java.Lang.ClassNotFoundException:在路径上找不到类“md57251f317a80041e1a60080af127573bd.GeolocationSingleListener”:DexPathList [[zip 文件“/data/app/com.companyname.PruebaMapas-1/base. apk"],nativeLibraryDirectories=[/data/app/com.companyname.PruebaMapas-1/lib/x86, /system/fake-libs, /data/app/com.companyname.PruebaMapas-1/base.apk!/lib /x86, /system/lib, /vendor/lib]] 我在谷歌上搜索,但没有找到任何东西。有什么想法吗?
  • 那是一个不同的问题,如果您在 stackoverflow 或一般 WEB 的现有线程中找不到答案,则应单独询问。
【解决方案2】:

您误解了“等待”的含义(很多开发人员似乎都是这样)。 使用“等待”会导致编译器返回到该异步方法的调用者(在您的情况下为 MapPage())并注册其余工作确实在该方法中完成(您正在等待什么)作为所谓的“续”。一旦完成,异步方法就会从中断的地方恢复执行。 因此,您所抱怨的最终正是系统的意图。 :-)

如果您绝对不希望系统继续运行,您可以让 SearchPosition() 返回一个 Task,然后在其上调用 .Wait()(参见 msdn page)。

如果我理解正确,您可能还想简单地摆脱异步模式并同步调用 SearchPosition()(“我只想等待 gps 坐标,但它会继续......”)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2018-02-15
    • 1970-01-01
    相关资源
    最近更新 更多