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

时间:2014-10-01 12:08:35

标签: c# multithreading windows-phone-8 xamarin.ios xamarin

我想在我的主页面加载时启动一个任务,它在后台使用Xamarin.Mobile来获取我的位置。难点是等待,如果此任务没有完成,当用户点击按钮时。

在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));
        }
    }
}

如果我的帖子中有一些语法错误抱歉我是法语。 :)

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:-1)

你应该做的一件事是用asnyc / await来重新排列它,因为你真的不需要在这种情况下创建任务,即(从我的头脑中):

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 one?