2013-01-07 105 views
0

這是我在板上的第一個問題。我正在使用WCF和MVVM模式編寫我的第一個企業級Silverlight(5)應用程序。我的問題是,我不明白如何讓模型類調用WCF服務,並且(這裏是問題),等待的結果返回給調用視圖模型之前。如何正確等待WCF異步

我看着msdn使用async和await關鍵字,但我不確定需要將哪些方法標記爲「async」。在我看來,該服務的自動生成的Reference.cs文件可能需要修改,但我有我的疑惑。更主要的是,我甚至不確定是否需要使用異步和等待,因爲我認爲它應該像我期望的那樣使用WCF。

無論如何,這裏是我有的模型類。我期望WCF調用完成後執行return語句,但事實並非如此:

public class CRMModel 
{ 
    ObservableCollection<CarrierInfo> carrierInfoCollection = new ObservableCollection<CarrierInfo>(); 

    public ObservableCollection<CarrierInfo> GetCarrierInformation() 
    { 
     var client = new CarrierRateService.CarrierRateServiceClient(); 
     client.GetCarrierInformationCompleted += (s, e) => 
     { 
      var info = e.Result; 
      carrierInfoCollection = info; 
      System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count); 

     }; 

     client.GetCarrierInformationAsync(); 

     System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count); 
     return carrierInfoCollection; 
    } 
} 

結果,正如你可能猜到了,就是:

關於與返回:0

剛剛得到結果集:3

非常感謝您的幫助! Francis

回答

0

感謝您的建議,Stpehen和託尼。直到我使用了this article中概述的方法時,我仍然一直在努力,虛擬機將回調方法傳遞給模型,該模型僅使用此方法調用WCF服務。

當我最初在模型中的匿名函數中指定了邏輯時,我遇到了與異步相關的時序問題。

我來自一個大型機背景,所以.NET中這種簡單的東西對我來說仍然是新穎的。 :)

3

歡迎來到SO!

首先,以使在Silverlight 5 asyncawait你需要安裝Microsoft.Bcl.Async package(目前處於測試階段)。

接下來,您需要說明WCF代理生成器不會生成兼容await的異步方法的事實。解決此問題的最簡單方法是在Visual Studio 2012「添加服務引用」對話框中選中相應的框。不過,我不是100%確定這可以用於Silverlight,所以如果沒有,你可以use TaskCompletionSource to create your own async-compatible wrapper

以下是完整的示例代碼:

public static Task<ObservableCollection<CarrierInfo>> GetCarrierInformationTaskAsync(this CarrierRateService.CarrierRateServiceClient @this) 
{ 
    var tcs = new TaskCompletionSource<ObservableCollection<CarrierInfo>>(); 

    @this.GetCarrierInformationCompleted += (s,e) => 
    { 
     if (e.Error != null) tcs.TrySetException(e.Error); 
     else if (e.Cancelled) tcs.TrySetCanceled(); 
     else tcs.TrySetResult(e.Result); 
    }; 
    @this.GetCarrierInformationAsync(url); 
    return tcs.Task; 
} 

現在,您可以等待使用下面的代碼是:

public ObservableCollection<CarrierInfo> GetCarrierInformation() 
{ 
    var client = new CarrierRateService.CarrierRateServiceClient(); 
    carrierInfoCollection = await client.GetCarrierInformationTaskAsync(); 
    System.Diagnostics.Debug.WriteLine("Just got the result set: " + carrierInfoCollection.Count); 

    System.Diagnostics.Debug.WriteLine("About to return with: " + carrierInfoCollection.Count); 
    return carrierInfoCollection; 
} 
+0

當然,真的嗎?我想我很驚訝,需要任何「特殊」才能使它與WCF一起工作。該選項在生成服務客戶端時被禁用。哦,謝謝你的幫助......我會看看我能想出什麼。 –

+0

聚苯乙烯 - 我應該說這個選項被選中,雖然複選框被禁用。 –