![](/img/trans.png)
[英]Use an object (Label) as a template for others in C# / Xamarin.Forms
[英]How to return an object from an async method (c# - 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;
}
这是异步方法(现在是一个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);
}
}
当我调用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;
}
你遇到的最大问题是你的构造函数试图调用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);
}
}
}
您需要从async
方法返回Task<T>
,不要让它返回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;
}
在调用方面,您还需要使该方法async
处理理想情况,但如果您想同步调用异步方法,那么在调用方面它将是:
var position = getCurrentPosition().Result;
// please note that it will be blocking call
// it is synchronously calling the async method
我不知道GetLocationAsync
的返回类型是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;
}
希望能帮助到你!
GetPositionAsync
返回Task<Position>
我想你应该用
public async Task<Position> getCurrentPosition() {
Position 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;
}
GetCurrentPosition现在具有返回类型void,因此如果要返回某个类型的值,则应定义返回类型。 因为它也是一个异步函数,GetCurrentPosition的返回类型应该是Task,如下所示:
public async Task<Position> getCurrentPosition() {
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
return position;
}
此外,调用函数应该使用等待如下:
Public PositionPage() {
Position position = await getCurrentPosition();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.