Windows Phone: Task.Delay 不工作/应用程序挂在页面上
Windows Phone: Task.Delay not working / Application hanging on a page
我正在制作 Windows Phone 8.1 的应用程序。当用户导航到应用程序的某个页面时,将调用 OnNavigatedTo() 方法中的一段代码。这是它的样子:
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()
不工作,让应用程序继续导航到页面?
没有 a good, minimal, complete code example,就无法确定您在这里真正想要什么。但是可以肯定的是,您似乎误解了 Task.Delay()
的作用,尽管缺乏细节,也许我们可以猜测一种修复代码的方法。
Task.Delay()
方法与任何异步方法一样, 不会 实际执行工作并等待 return 直到完成。相反,通过调用它,您是在告诉方法您希望延迟发生,并且该方法通过 return 给您一个 Task
实例来响应,您可以使用该实例来确定何时工作(即延迟)实际上已经完成了。
利用这个的正常方法是使用 await
语句,要使用它你必须有一个 async
方法。这实际上 很好 ,因为如果我们将您的 OnNavigatedTo()
方法变成 async
方法,那么它可以立即 return 让您的程序继续运行处理它需要做的事情,而不是锁定您的用户界面。
因此,例如,我们可能会将方法更改为更像这样:
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...
}
}
现在,这非常重要:在任何 "stuff" 该方法也执行的操作中,您需要确保所有 "stuff" 都可以快速完成。您不想让该方法花费大量时间来做任何事情;只是正常的 UI 相关操作和少量计算。
如果该方法确实需要做任何耗时的事情以至于用户会注意到 UI 在该代码运行时被冻结,您需要(最好)将该代码分离到不同的方法,然后从 Task
实例调用该方法,等待 Task
。例如,await Task.Run(() => MyLengthyOperation());
.
我正在制作 Windows Phone 8.1 的应用程序。当用户导航到应用程序的某个页面时,将调用 OnNavigatedTo() 方法中的一段代码。这是它的样子:
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()
不工作,让应用程序继续导航到页面?
没有 a good, minimal, complete code example,就无法确定您在这里真正想要什么。但是可以肯定的是,您似乎误解了 Task.Delay()
的作用,尽管缺乏细节,也许我们可以猜测一种修复代码的方法。
Task.Delay()
方法与任何异步方法一样, 不会 实际执行工作并等待 return 直到完成。相反,通过调用它,您是在告诉方法您希望延迟发生,并且该方法通过 return 给您一个 Task
实例来响应,您可以使用该实例来确定何时工作(即延迟)实际上已经完成了。
利用这个的正常方法是使用 await
语句,要使用它你必须有一个 async
方法。这实际上 很好 ,因为如果我们将您的 OnNavigatedTo()
方法变成 async
方法,那么它可以立即 return 让您的程序继续运行处理它需要做的事情,而不是锁定您的用户界面。
因此,例如,我们可能会将方法更改为更像这样:
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...
}
}
现在,这非常重要:在任何 "stuff" 该方法也执行的操作中,您需要确保所有 "stuff" 都可以快速完成。您不想让该方法花费大量时间来做任何事情;只是正常的 UI 相关操作和少量计算。
如果该方法确实需要做任何耗时的事情以至于用户会注意到 UI 在该代码运行时被冻结,您需要(最好)将该代码分离到不同的方法,然后从 Task
实例调用该方法,等待 Task
。例如,await Task.Run(() => MyLengthyOperation());
.