异步操作不会停止在等待命令

时间:2018-01-05 10:18:32

标签: c# android asynchronous xamarin gps

我想在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坐标,但它会继续,然后转到&#34; MoveToRegien&#34;在我有gps坐标之前。我不明白为什么,有人可以帮助我吗?谢谢!

2 个答案:

答案 0 :(得分:3)

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

这可能是您的问题,因此请将其更改为:

async Task SearchPosition()

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

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

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

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

修改
我想我现在看到了你真正的问题。您正试图在构造函数中找到一个位置,因此您不等待异步SearchPosition()方法。

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

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

答案 1 :(得分:2)

你误解了“等待”的含义(对于很多开发者来说似乎就是这种情况)。 使用“await”会导致编译器返回到该异步方法的调用者(在您的情况下为MapPage())并注册其余的工作,在该方法中完成(您正在等待的)作为所谓的“延续”。一旦完成,异步方法就会从中断处继续执行。 所以,你所抱怨的最终正是系统的意图。 : - )

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

如果我理解正确的话,你也可能只想摆脱异步模式并同步调用SearchPosition()(“我想要的只是等待gps坐标,但它会继续......”)。