2011-04-29 28 views
1

我正在使用.NET 4和SL 4. 我想從我的Silverlight頁面的代碼中抽取出DAL的數據檢索部分。 理想情況下,將它作爲我的Silverlight應用程序和REST API調用之間的接口層安裝到它自己的DLL中。 我的意圖是不使用RIA服務,因爲我已經有一個使用REST API調用的DLL的現有DAL。Silverlight 4:REST API調用數據檢索層?

問題是異步的「WebClient」回調過程。 我知道我可以利用WebClient類進行REST調用,然後註冊異步處理程序以簡單地將該調用的結果綁定到UI。 但在我的情況下,我想把它抽象成它自己的DLL。基本上......讓它同步。

按定義,異步調用在這裏有問題,因爲它不能立即直接返回某種類型的IEnumerable。

任何人都可以指向一個樣本/教程,這樣的事情正在做?

RIA使得方法調用單獨的DLL爲IEnumerable的數據收集

這種方法使得REST API調用來檢索數據,然後返回IEnumerable的到RIA並綁定到用戶界面。

+1

將您的用戶界面綁定到一個屬性,該屬性通過ObservableCollection 返回IEnumerable。這樣,用戶界面可以綁定到一個空列表,並且數據以異步或同步方式返回時,只需簡單地自行更新。 – 2011-04-29 21:41:41

回答

2

將它直接下調到fundementals實際上你要求的是能夠對執行異步任務的API進行同步調用,但只有在該異步任務完成時纔會返回。爲了說明另一種想要將異步操作的Begin和End階段重新組合爲單個原子同步操作的方式。

獲得的唯一方法是阻止進行調用的線程,直到達到異步操作的結束階段。由於多種原因,這不是一個好主意。

如果您認真對待使用Silverlight,您必須吞併其異步特性並在該框架中使用,而不是試圖強制它回到同步系統中。

轉換同步對異步

有這個blog約同步碼轉換爲異步代碼的讀取。看了那現在讓我們試想一下,你的代碼使用名爲DownloadYourDataObjects在新的DLL同步方法,它有這個虛構的簽名: -

public IEnumerable<YourDataObject> DownloadYourDataObjects(Uri source); 

在內部它使用WebClient從REST基本服務下載一個字符串,並將其轉換到一組YourDataObject實例。虛同步代碼,以顯示這組數據可能是: -

private void btnLoadMyData_Click(object sender, RoutedEventArgs e) 
{ 
     try 
     { 
      LoadMyData(); 
     } 
     catch (Exception err) 
     { 
      // Oops something bad happened show err. 
     } 
} 

private void LoadMyData() 
{ 
     DataItemsListBox.ItemsSource = DownloadYourDataObjects(someUri); 
} 

由於Silverlight WebClient是異步的,我們需要把這個整個的代碼轉換鏈以異步方式工作。

使用博客中的AsyncOperationService,我們首先需要將DownloadYourDataObjects轉換爲返回AsyncOperation。這將有這樣的簽名(見稍後再實現的想法): -

public AsyncOperation DownloadYourDataObjects(Uri source, Action<IEnumerable<YourDataObject>> returnResult); 

的使用代碼將然後是這個樣子: -

private void btnLoadMyData_Click(object sender, RoutedEventArgs e) 
{ 
     LoadMyData().Run(err => 
     { 
      if (err != null) 
      { 
       // Oops something bad happened show err. 
      } 
     }); 
} 

private IEnumerable<AsyncOperation> LoadMyData() 
{ 
     yield return DownloadYourDataObjects(someUri, result => 
     { 
      DataItemsListBox.ItemsSource = result; 
     }); 
} 

這看起來豆蔻OTT但在事實上它並不比原來的「同步」版本多得多。在這種簡單的情況下,LoadMyData只有一個操作要執行。更復雜的版本LoadMyData可能有多個其他操作也需要異步。在這種情況下,這些操作將只是代碼中的其他yield點,LoadMyData的基本邏輯結構不會從原始同步版本變化很多。

這裏是您的DLL將提供的DownloadYourDataObjects的實現示例。

public AsyncOperation DownloadYourDataObjects(Uri source, Action<IEnumerable<YourDataObject>> returnResult) 
{ 
    return (completed) => 
    { 
     WebClient client = new WebClient(); 
     client.DownloadStringCompleted += (s, args) => 
     { 
      try 
      { 
       returnResult(ConvertStringToYourDataObjects(args.Result)); 
       completed(null); 
      } 
      catch (Exception err) 
      { 
       completed(err); 
      } 
     }; 
     client.DownloadStringAsync(source); 
    }; 
} 
+0

這看起來正是我在找的東西,謝謝! – 2011-04-29 21:58:31