C# 正在等待GetGeopositionAsync()的结果
我正在开发WinPhone 8应用程序。 此应用程序上有一个按钮“发送短信”。 当用户单击此按钮时,应发生两件事:C# 正在等待GetGeopositionAsync()的结果,c#,.net,geolocation,task-parallel-library,async-await,C#,.net,Geolocation,Task Parallel Library,Async Await,我正在开发WinPhone 8应用程序。 此应用程序上有一个按钮“发送短信”。 当用户单击此按钮时,应发生两件事: (方法A)获取当前位置的地理坐标(使用Geolocator和GetGeopositionAsync) (方法B)编写并发送一条短信,其中地理坐标是身体的一部分 问题在于:GetGeopositionAsync是一种异步方法。在检测到坐标(需要几秒钟)之前,会发送SMS(当然没有坐标) 我如何告诉方法2等待坐标可用 好的,这是我的代码: 当用户按下按钮时,坐标由第一种方法确定,第二种
private void btnSendSms_Click(object sender, RoutedEventArgs e)
{
GetCurrentCoordinate(); // Method 1
// -> Gets the coordinates
SendSms(); // Method 2
// Sends the coordinates within the body text
}
第一个方法GetCurrentCoordinate()如下所示:
...
private GeoCoordinate MyCoordinate = null;
private ReverseGeocodeQuery MyReverseGeocodeQuery = null;
private double _accuracy = 0.0;
...
private async void GetCurrentCoordinate()
{
Geolocator geolocator = new Geolocator();
geolocator.DesiredAccuracy = PositionAccuracy.High;
try
{
Geoposition currentPosition = await geolocator.GetGeopositionAsync(
TimeSpan.FromMinutes(1),
TimeSpan.FromSeconds(10));
lblLatitude.Text = currentPosition.Coordinate.Latitude.ToString("0.000");
lblLongitude.Text = currentPosition.Coordinate.Longitude.ToString("0.000");
_accuracy = currentPosition.Coordinate.Accuracy;
MyCoordinate = new GeoCoordinate(
currentPosition.Coordinate.Latitude,
currentPosition.Coordinate.Longitude);
if (MyReverseGeocodeQuery == null || !MyReverseGeocodeQuery.IsBusy)
{
MyReverseGeocodeQuery = new ReverseGeocodeQuery();
MyReverseGeocodeQuery.GeoCoordinate = new GeoCoordinate(
MyCoordinate.Latitude,
MyCoordinate.Longitude);
MyReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted;
MyReverseGeocodeQuery.QueryAsync();
}
}
catch (Exception)
{ // Do something }
}
private void ReverseGeocodeQuery_QueryCompleted(object sender,
QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
lblCurrAddress.Text = address.Street + " " + address.HouseNumber + ",\r" +
address.PostalCode + " " + address.City + ",\r" +
address.Country + " (" + address.CountryCode + ")";
}
}
}
}
问题是,当方法SendSms()设置SmsComposeTask对象时,所有这些文本框(lblationate、lblLongitude、lblCurrAddress)仍然为空。
我必须确保在方法SendSms()启动之前已经设置了文本框。除非是UI事件处理程序,否则几乎不应该将方法标记为
async void
。您正在调用一个异步方法,而不等待它结束。您基本上是并行调用这两个方法,因此很清楚为什么坐标不可用
您需要使GetCurrentCoordinate
返回一个等待的任务并等待它,如下所示:
private async Task GetCurrentCoordinateAsync()
{
//....
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinateAsync();
// You'll get here only after the first method finished asynchronously.
SendSms();
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinate();
SendSms();
}
除非方法是UI事件处理程序,否则几乎不应该将其标记为async void。您正在调用一个异步方法,而不等待它结束。您基本上是并行调用这两个方法,因此很清楚为什么坐标不可用 您需要使
GetCurrentCoordinate
返回一个等待的任务并等待它,如下所示:
private async Task GetCurrentCoordinateAsync()
{
//....
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinateAsync();
// You'll get here only after the first method finished asynchronously.
SendSms();
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinate();
SendSms();
}
这是您应该避免
async void
的主要原因之一void
对于async
方法来说是一种非常不自然的返回类型
首先,将GetCurrentCoordinate
设置为async任务
方法,而不是async void
。然后,您可以将单击处理程序更改为如下所示:
private async Task GetCurrentCoordinateAsync()
{
//....
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinateAsync();
// You'll get here only after the first method finished asynchronously.
SendSms();
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinate();
SendSms();
}
单击处理程序是
async void
,这只是因为事件处理程序必须返回void
。但是您应该在所有其他代码中真正努力避免async void
。这是您应该避免async void
的主要原因之一void
对于async
方法来说是一种非常不自然的返回类型
首先,将GetCurrentCoordinate
设置为async任务
方法,而不是async void
。然后,您可以将单击处理程序更改为如下所示:
private async Task GetCurrentCoordinateAsync()
{
//....
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinateAsync();
// You'll get here only after the first method finished asynchronously.
SendSms();
}
private async void btnSendSms_Click(object sender, RoutedEventArgs e)
{
await GetCurrentCoordinate();
SendSms();
}
单击处理程序是
async void
,这只是因为事件处理程序必须返回void
。但您应该真正努力避免在所有其他代码中出现异步无效。这里有两件事您做错了:
在需要等待时使用void returningasync
方法。这是不好的,因为您不能等待这些方法的执行,并且只能在无法使方法返回Task
或Task
时使用。这就是为什么在调用SendSms
时,文本框中看不到任何内容
混合UI和非UI代码。您应该在UI和非UI代码之间传输数据,以避免具有不同职责的代码之间的紧密耦合。它还使阅读和调试代码变得容易
ReverseGeocodeQuery
没有可等待的异步API,但:
这有意义吗?这里有两件事你做错了:
在需要等待时使用void returningasync
方法。这是不好的,因为您不能等待这些方法的执行,并且只能在无法使方法返回Task
或Task
时使用。这就是为什么在调用SendSms
时,文本框中看不到任何内容
混合UI和非UI代码。您应该在UI和非UI代码之间传输数据,以避免具有不同职责的代码之间的紧密耦合。它还使阅读和调试代码变得容易
ReverseGeocodeQuery
没有可等待的异步API,但:
这有意义吗?您应该尝试使用代码自己解决问题。您应该尝试使用代码自己解决问题。非常感谢。就这样,非常感谢。就这样。