2011-03-02 106 views
1
public class AllViewModel 
{ 

    private List<Settings> SettingsList; 

    public ViewAgendaAllViewModel() 
    { 
     client.SupplierListWithSettings(GetSupplierListWithSettings_Completed) 
    } 

    public void GetSupplierListWithSettings_Completed(object sender, Supplier_GetListWithSettingsCompletedEventArgs e) 
    { 

     if (e.Error == null) 
     { 
      if (e.Result != null) 
      { 
       SettingsList = new List<Settings>(); 
       foreach (VCareSupplierDto obj in e.Result) 
       { 
        SettingsList.Add(obj); 

       } 
      } 

     } 
    } 
} 

問題:由於異步呼叫,Settinglist propery沒有設置。如何使WCF異步呼叫

這是我的課,我想SYNCHRONUS呼叫ServiceMethod SupplierListWithSettings。

當我將創建AllViewModel的情況下,應該裝有設置。

預期:當我將創建AllViewModel的情況下它應該包含SettingList財產。

回答

1

更正:設置列表設置,但它聽起來像它沒有設置一旦你想。

這聽起來像你問這個:當你構建AllViewModel的一個實例,您希望SettingsList屬性將AllViewModel構造函數返回前應充分填充。

雖然可以做到這一點,有很多原因,這可能不是一個好主意,一個可疑的設計要求。只要網絡請求完成(可能需要20到30秒),將網絡調用變爲同步調用將阻止調用線程(通常是您的UI線程)。你真的想讓你的應用程序UI凍結30秒嗎?您的用戶很可能會認爲您的程序崩潰或「鎖定」,並會關閉該程序,甚至沒有意識到程序並未死亡。

儘管如此,這裏是如何做到這一點:您可以將異步調用轉換爲使用像這樣使用.NET 4.0任務並行庫(TPL)同步調用(未經測試):

public AllViewModel() 
{ 
    var task = Task<List<Settings>>.Factory.StartNew(() => 
        client.SupplierListWithSettings((s,e) => 
        { 
         if (e.Error == null && e.Result != null) 
         { 
          var list = new List<Settings>(); 
          foreach (VCareSupplierDto obj in e.Result) 
          { 
           list.Add(obj); 
          } 
          task.SetResult(list); 
         } 
        })); 
    this.SettingsList = task.Result; 
} 

同樣,這不是一個好主意。對於你來說,看看你的代碼的哪些部分假定在構造對象後立即填充SettingsList屬性,並更改這些依賴關係來執行某些操作,例如監聽SettingsList屬性的更改並將其工作作爲很快,SettingsList實際上是異步填充的。

嘗試去與異步流,而不是反對它的戰鬥。

+0

我認爲你應該強調一點,這是一個壞主意(凍結UI等)。是否有可能在'SettingsList'屬性的setter方法中觸發一個事件? – froeschli 2011-03-02 07:03:46

+1

@froeschli:考慮到超過一半的文本致力於強調這是一個壞主意,我認爲我們已經涵蓋了這一點。 ;>「聽取對SettingsList屬性的更改」通常是通過觸發一個事件來完成的,特別是IPropertyChangedNotification規範。 – dthorpe 2011-03-02 16:57:40

+0

點了。感謝您的跟進。 – froeschli 2011-03-02 18:11:37