异步操作不会在 await 命令处停止

Async operation does not stop at await command

我想在 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"。我不明白为什么,有人可以帮助我吗?谢谢!

在您的 SearchPosition 方法中 return 使用 void 而不是 Task 有什么特殊原因吗?

这可能是你的问题,所以将其更改为:

async Task SearchPosition()

实际上我会把它改成return一个位置:

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;
    }
}

你误解了"await"的意思(好像很多开发者都这样)。 使用 "await" 会导致编译器 return 到该异步方法的调用者(在您的情况下为 MapPage())并注册其余工作在该方法中完成(您正在等待)正所谓"continuation"。一旦完成,异步方法就会从中断处恢复执行。 因此,您所抱怨的最终正是系统的目的。 :-)

如果您确实不希望系统继续运行,您可以将 SearchPosition() return 设为一个任务,然后对其调用 .Wait()(参见 msdn page)。

如果我理解正确的话,您可能还想简单地摆脱异步模式并同步调用 SearchPosition() ("All I want is to wait for the gps coordinates, but it continues...")。