den*_*nno 2 c# asynchronous async-await xamarin xamarin.forms
在Xamarin.Forms应用程序中,我使用GeoLocator来检索有关我的位置的信息.该方法是异步的.我必须返回包含位置参数的对象,但我不能.
这是我的类PositionPage的构造函数
public PositionPage()
{
getCurrentPosition();
var map = new Map(
MapSpan.FromCenterAndRadius(
new Position(45.987487, 9.366337), Distance.FromMiles(0.3)))
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
Content = stack;
}
Run Code Online (Sandbox Code Playgroud)
这是异步方法(现在是一个void方法):
public async void getCurrentPosition()
{
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
Debug.WriteLine("Position Status: {0}", position.Timestamp);
Debug.WriteLine("Position Latitude: {0}", position.Latitude);
Debug.WriteLine("Position Longitude: {0}", position.Longitude);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用getCurrentPosition()在MapSpan中传递它时,我需要返回一个位置对象.
我怎样才能做到这一点?
没有其他答案似乎解决了您的代码的主要问题,所以我将添加我的答案.
你有一个异步方法getCurrentPosition().这个方法等待一个电话:locator.GetPositionAsync(timeoutMilliseconds: 10000).这段代码唯一的问题是你没有返回你得到的结果locator.GetPositionAsync().您可以通过这样做来解决这个问题:
//SomeType needs to be the same type that locator.GetPositionAsync() returns
//Also C# naming conventions say that any async methods should end with "Async",
//obviously not required but it will make your life easier later
public async Task<SomeType> GetCurrentPositionAsync()
{
SomeType position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
Debug.WriteLine("Position Status: {0}", position.Timestamp);
Debug.WriteLine("Position Latitude: {0}", position.Latitude);
Debug.WriteLine("Position Longitude: {0}", position.Longitude);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
return position;
}
Run Code Online (Sandbox Code Playgroud)
你遇到的最大问题是你的构造函数试图调用async方法,这将是一个同步调用,它基本上否定了async/await的好处.
我强烈建议更改此应用程序的设计,以便您利用async/await.它不一定是一个重大变化.您可以实现构造对象并为您返回的静态异步方法,这样您就可以等待该调用.像这样的东西:
public class PositionPage
{
public static async Task<PositionPage> CreateAsync()
{
var position = await GetCurrentPositionAsync();
var map = new Map(
MapSpan.FromCenterAndRadius(
new Position(45.452481, 9.166337),
Distance.FromMiles(0.3)))
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
var positionPage= new PositionPage();
positionPage.Content = stack;
return positionPage;
}
private PositionPage()
{
}
//SomeType needs to be the same type that locator.GetPositionAsync() returns
//Also C# naming conventions say that any async methods should end with "Async", obviously not required but it will make your life easier later
public async Task<SomeType> GetCurrentPositionAsync()
{
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
Debug.WriteLine("Position Status: {0}", position.Timestamp);
Debug.WriteLine("Position Latitude: {0}", position.Latitude);
Debug.WriteLine("Position Longitude: {0}", position.Longitude);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要Task<T>从async方法中返回,不要使其返回void,您需要重构该方法,例如:
public async Task<Geoposition> getCurrentPosition()
{
Geoposition position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
Debug.WriteLine("Position Status: {0}", position.Timestamp);
Debug.WriteLine("Position Latitude: {0}", position.Latitude);
Debug.WriteLine("Position Longitude: {0}", position.Longitude);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
return position;
}
Run Code Online (Sandbox Code Playgroud)
在调用方,您还需要async为理想场景创建该方法,但如果您想同步调用异步方法,那么在调用方,它会像:
var position = getCurrentPosition().Result;
// please note that it will be blocking call
// it is synchronously calling the async method
Run Code Online (Sandbox Code Playgroud)
我不知道 的返回类型是什么GetLocationAsync,但它会返回,Task<T>其中T将是某种特定类型,因此最好将方法的返回类型设置为Task<Geoposition>,假设它返回Task<Geoposition>,但您可以将其替换为任何返回类型的GetPositionAsync方法。
或者,您可能想保持getCurrentPosition同步,可以这样做:
public Geoposition getCurrentPosition()
{
Geoposition position = null;
try
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
position = locator.GetPositionAsync(timeoutMilliseconds: 10000).Result;
Debug.WriteLine("Position Status: {0}", position.Timestamp);
Debug.WriteLine("Position Latitude: {0}", position.Latitude);
Debug.WriteLine("Position Longitude: {0}", position.Longitude);
}
catch (Exception ex)
{
Debug.WriteLine("Unable to get location, may need to increase timeout: " + ex);
}
return position;
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
6304 次 |
| 最近记录: |