2015-02-09 61 views
0

我正在为Windows Phone 8.1生成应用程序。当用户导航到应用程序的某个页面时,会调用OnNavigatedTo()方法中的一段代码。这里是什么样子:Windows Phone:Task.Delay不工作/挂在页面上的应用程序

protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
    while (!hasUserWonGame) 
    { 
     Task.Delay(3000); 
     //do stuff... 
     Task.Delay(6000); 
     //do more stuff... 
     Task.Delay(2000); 
     //do more stuff... 
    } 
} 

调试时,有一次我点击了按钮导航到该页面时,应用程序只需在该页面被绞死,甚至没有导航到该页面。评论while封锁,应用程序工作正常。如果您在以外的区域添加任何语句,它也可以正常工作。然而,在循环的最小部分发表评论,即使使用Task.Delay,也会让我陷入(基本上)在while (true)循环中。

问题是,用户甚至无法导航到页面,因此无法将hasUserWonGame更改为true。为什么Task.Delay()无法工作,并让应用程序继续导航到页面?

回答

1

没有a good, minimal, complete code example,这是不可能知道你真正想要在这里。但是可以肯定的是,您似乎误解了Task.Delay()的功能,也许我们可以通过一种方法来解决问题,尽管缺乏细节。

Task.Delay()方法与其他异步方法一样,不是实际上执行工作并等待返回,直到完成。相反,通过调用它,您告诉您希望延迟发生的方法,并且该方法通过返回一个实例来响应,您可以使用该实例确定实际完成该工作(即延迟)的时间。

利用此功能的正常方法是使用await语句,并使用该语句必须具有async方法。这实际上是好的,因为如果我们使OnNavigatedTo()方法成为async方法,那么它可以立即返回并让程序继续执行它需要做的事情,而不是锁定用户界面。

所以,举例来说,我们可能会改变看起来更像这样的方法:

protected async override void OnNavigatedTo(NavigationEventArgs e) 
{ 
    while (!hasUserWonGame) 
    { 
     await Task.Delay(3000); 
     //do stuff... 
     await Task.Delay(6000); 
     //do more stuff... 
     await Task.Delay(2000); 
     //do more stuff... 
    } 
} 

现在,这是非常重要的:在任何“东西”这个方法还没有,你需要确保这些都是可以快速完成的“东西”。你不想让这种方法花费大量的时间做任何事情;只是普通的UI相关操作和少量的计算。

如果该方法确实需要做足够耗时的任何事情,以至于用户会注意到UI在代码运行时会被冻结,您需要(最好)将该代码分离出不同的方法,然后调用该方法来自Task实例,正在等待Task。例如,像await Task.Run(() => MyLengthyOperation());之类的东西。

+0

我最近了解到'async'和'await',其实我是(直到现在)依靠Visual Studio来突出显示绿色波浪线的异步方法......我想我已经吸取了教训。 – 2015-02-09 02:31:18