在Windows Phone中运行异步任务并稍后等待

问题描述:

我想在加载主页时启动一个任务,这会在后台使用Xamarin.Mobile获取我的位置。难点在于等待,如果这个任务没有完成,当用户点击一个按钮时。在Windows Phone中运行异步任务并稍后等待

在Xamarin的iOS,我设法做到这一点,但是当我试图做同样在Windows Phone 8.0,我得到一个AggregateException与作为消息:“一个或多个错误发生。”

还有就是我使用的代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Navigation; 
using Microsoft.Phone.Controls; 
using Microsoft.Phone.Shell; 
using System.Diagnostics; 
using System.IO; 
using Microsoft.Phone.Scheduler; 
using System.Threading; 
using System.Threading.Tasks; 
using System.ComponentModel; 
using Xamarin.Geolocation; 

namespace Application.WinPhone 
{ 
    public partial class Connexion : PhoneApplicationPage 
    { 
     static Task w; 

     // Constructor 
     public Connexion() 
     { 
      InitializeComponent(); 

      w = new Task (() => 
      { 
       Debug.WriteLine("Start"); 
       Geolocator geolocator = null; 

       geolocator = new Geolocator() { DesiredAccuracy = 50}; 

       var t = geolocator.GetPositionAsync(8000).ContinueWith(x => 
       { 
        Debug.WriteLine(string.Format("Latitude : {0} Longitude : {1}",  x.Result.Latitude, x.Result.Longitude)); //Visual Studio's debugger indicate this line with the exception 
       }); 
       t.Wait(); 
       Debug.WriteLine("Finished"); 
      }); 
      w.Start(); 

     } 

     private void Connexion_Click(object sender, RoutedEventArgs e) 
     { 
       w.Wait(); 

       //Here use the position find by the task to know on which page send the user 
       NavigationService.Navigate(new Uri("/Inscription.xaml", UriKind.RelativeOrAbsolute)); 
     } 
    } 
} 

如果在我的岗位对不起一些语法错误,我是法国人。 :)

在此先感谢您的帮助。

+0

检查AggregateException的'InnerException'属性以了解发生了什么 – 2014-10-01 12:26:58

+0

InnerException的消息说:“任务被取消”。 为什么这个任务会被取消? – Nunshakin 2014-10-01 13:02:05

+0

你正在构造函数中完成这个任务,那叫什么?也许它耗时太长,有什么东西在杀死它? – valdetero 2014-10-01 14:18:12

有一件事你真正应该做的是与asnyc到rearange它/等待,你真的不需要在这种情况下创建任务,即(从我的头):

public Connexion() 
{ 
    Connexion.IsEnabled = false; 
    var ignore = InitAsync(); 
} 
private async Task InitAsync() 
{ 
      Debug.WriteLine("Start"); 
      Geolocator geolocator = null; 

      geolocator = new Geolocator() { DesiredAccuracy = 50}; 

      var result = await geolocator.GetPositionAsync(8000); 
       Debug.WriteLine(string.Format("Latitude : {0} Longitude : {1}",  result.Latitude, result.Longitude)); //Visual Studio's debugger indicate this line with the exception 
      Connexion.IsEnabled = true; 
} 

注意按钮应该除非行动成功,否则将被禁用。你还应该在这里添加try/catch处理程序,你会得到更清晰的异常(也许Geolocator不能在非UI线程中创建?) 除了你实际使用的Geolocator类 - Forms Labs之一?

+1

您应该不会忽略正在初始化类型。调用者不可能真正知道实例何时可以安全使用,并且在使用不安全时不会阻止他们使用该类型。 – Servy 2014-10-01 14:41:05

+0

在这种情况下,它可以(至少在本例中) - 除非geolocator找到位置,否则不会启用按钮。但一般情况下,这取决于你在做什么。 – 2014-10-01 14:50:16

+0

我尝试了你的解决方案,但是我遇到了同样的问题,我没有超越这一行:await geolocator.GetPositionAsync(8000); 这是一个例外:任务被取消。 – Nunshakin 2014-10-01 14:52:33

首先,你不应该在构造函数中做任何繁重的工作。这是一个design flaw。其次,Windows Phone预计您的应用程序为start in a limited amount of time,即最多10秒。因此,启动应用程序并等待Geolocator 8秒钟可能会花费太多时间,因此取消的任务。

你可以做的是在页面的构造函数中创建Geolocator并获取OnNavigatedTo事件中的位置。

+0

不幸的是,我得到了同样的错误任务被取消。 – Nunshakin 2014-10-02 08:54:22