异步操作不会在 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...")。
我想在 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...")。