2015-02-09 41 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

相關問題