2014-03-04 99 views
1

我有一個WinRT應用程序,它使用Nito.AsyncEx庫。我有一個財產,實施INotifyTaskCompletion。它適用於數據綁定到屬性的XAML項目。我現在發現自己處於一種需要等待屬性從代碼隱藏上下文獲得非空結果的情況。目前,我正在使用異步方法,該方法使用Task.Delay()語句循環,直到屬性Result爲非null。有沒有更有效的方法來做到這一點,最好是支持暫停和檢查超時情況的方法?以等待方式等待INotifyTaskCompletion屬性的結果?

請注意,檢索滿足INotifyTaskCompletion屬性的URL的代碼將從ViewModel的構造函數中觸發。

這裏是我目前使用的代碼:

/// <summary> 
    /// Waits for the rate and review URL to show up or until the time-out limit expires. 
    /// </summary> 
    /// <param name="timeoutSecs">The number of seconds to wait before giving up.</param> 
    /// <returns>Returns the rate & review URL if it was retrieved, NULL if the request timed-out</returns> 
    async private Task<string> WaitForRateAndReviewUrlAsync(int timeoutSecs = 30) 
    { 
     DateTime dtStart = DateTime.Now; 
     bool bIsTimedOut = false; 

     if (timeoutSecs < 0) 
      throw new ArgumentException("The time-out value is negative."); 

     while (String.IsNullOrWhiteSpace(GetMainViewModel.RateAndReviewURL.Result) && !bIsTimedOut) 
     { 
      await Task.Delay(1000); 

      bIsTimedOut = (DateTime.Now - dtStart).TotalSeconds >= timeoutSecs; 
     } // while() 

     return GetMainViewModel.RateAndReviewURL.Result; 
    } 
+0

所以,你的代碼可以做到這一點。然後在你的代碼背後,你知道什麼時候價值已經根據你的一套規則而改變了。 – TYY

回答

3

INotifyTaskCompletion公開它包裝的任務,如Task屬性。如果您有視圖模型的控制你爲什麼不去做個檢查,並有激發關閉事件樣的EventAggregator工作方式

/// <summary> 
/// Waits for the rate and review URL to show up or until the time-out limit expires. 
/// </summary> 
/// <param name="timeoutSecs">The number of seconds to wait before giving up.</param> 
/// <returns>Returns the rate & review URL if it was retrieved, NULL if the request timed-out</returns> 
async private Task<string> WaitForRateAndReviewUrlAsync(int timeoutSecs = 30) 
{ 
    if (timeoutSecs < 0) 
    throw new ArgumentException("The time-out value is negative."); 
    var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSecs)); 
    var completedTask = await Task.WhenAny(timeoutTask, GetMainViewModel.RateAndReviewURL.Task); 
    if (completedTask == timeoutTask) 
    return null; 
    return GetMainViewModel.RateAndReviewURL.Result; 
} 
+0

謝謝斯蒂芬。 Nito.AsyncEx是一個很棒的圖書館。 –

+0

如果需要,將取消標記加入混音以取消這兩項任務的最簡單方法是什麼? –

+0

你想將令牌傳遞給你的'async'方法; 'Task.Delay'具有一個也需要令牌的重載。 –

2

只是await的任務,而不是同步等待任務完成,然後再進行檢查等待一段時間:

var result = await GetMainViewModel.RateAndReviewURL; 

while(result != null) 
{ 
    result = await GetMainViewModel.RateAndReviewURL; 
} 

return result;