2014-09-24 47 views
3

我有一個WPF應用程序,其中查看模型中的某個屬性將填充爲對服務的調用。到目前爲止,我一直在關注Stephen Cleary的優秀教程。他討論了這樣做的一種方法here多次調用異步方法

在我的情況下,視圖模型每個應用程序實例化一次。應用程序在視圖模型上調用Initialise方法(自定義方法),傳遞一些信息,View模型應該根據這些信息與服務聯繫以獲取實例化的屬性。

問題是應用程序可以多次調用Initialise方法(用戶隨機移動)傳遞一組新信息。發生這種情況時,我需要放棄早先運行的任務(如果有的話),這些任務在上次調用Initialise時調用該服務,並用新的一組信息調用該服務,並確保該屬性僅綁定到最新調用的結果。

有人可以幫助想出一個模式來實現這一目標嗎?基本上多次調用一個異步方法,但只保留最後的結果。

+0

你會同時多次打電話給他們嗎?或者你的應用程序會調用'Initialize'方法幾次,但是在調用之間有差異? – 2014-09-24 12:50:56

+0

當用戶單擊按鈕時會調用初始化方法,這樣調用將不會是併發的,而是順序的。 – Nikhil 2014-09-24 12:53:09

回答

1

基本上,您要取消以前調用Initialize方法。而在TPL中,如果你想取消某些東西,你通常應該使用CancellationToken

您可以這樣做的方式是在您的視圖模型中有一個CancellationTokenSource類型的字段,表示取消最後一次調用Initialize。當您運行Initialize時,它將取消先前的調用,設置自己的取消,調用服務,然後只在未請求取消時才設置屬性。在代碼:

class ViewModel 
{ 
    // default value just to avoid a null check 
    private CancellationTokenSource intializationCancellation = 
     new CancellationTokenSource(); 

    public async Task InitializeAsync(int parameter) 
    { 
     // cancel previous initialization, if any 
     intializationCancellation.Cancel(); 

     var cts = new CancellationTokenSource(); 
     intializationCancellation = cts; 

     var value = await GetValueaAsync(parameter); 

     if (cts.Token.IsCancellationRequested) 
      return; 

     Value = value; 
    } 

    private async Task<string> GetValueAsync(int parameter) 
    { 
     // call the external service here 
    } 

    public string Value { get; private set; } 
} 

如果服務你調用支持取消,你應該通過CancellationToken它太,這很可能節省一些資源。如果你這樣做,不要忘記趕上OperationCanceledException(因爲我相信你不希望Initialize拋出,即使它被取消)。

+0

你的答案是正確的,但不適用於我的問題。鑑於COM Interop的高級別,我也不得不處理,有沒有直接的模式,可以幫助解決這個問題。事情也很複雜,因爲我需要確保運行任務的線程是TPL不能保證的STA。總而言之,我不得不重新設計一點點,但我現在有一些工作要做。無論如何謝謝你! – Nikhil 2014-11-14 03:41:16