2011-05-16 71 views
0

我想了解如何最好地使用Reactive Extensions庫並設置了簡單的測試WPF應用程序來查看日誌記錄數據庫表。在ViewModel類中,我將一個ObservableCollection與從Linq到Sql的前100個日誌條目填入DataContext,我試圖使用Rx來保持UI的響應。處理數據庫連接異常與Linq to SQL和Rx

下面的代碼片段工作,除非數據庫不可用,此時應用程序會引發異常並崩潰。哪裏會是處理數據庫連接異常的最佳位置,以及爲什麼它們不由Observer的OnError方法處理?

ObservableCollection<LogEntry> _logEntries = new ObservableCollection<LogEntry>(); 

DataContext dataContext = new DataContext("connection string"); 

(from e in dataContext.LogEntries 
    select e).Take(100).ToObservable() 
    .SubscribeOn(Scheduler.ThreadPool) 
    .ObserveOnDispatcher() 
    .Subscribe(_logEntries.Add, ex => System.Diagnostics.Debug.WriteLine(ex.ToString())); 

回答

2

試試這個,而不是ToObservable:

public static IObservable<T> SafeToObservable(this IEnumerable<T> This) 
{ 
    return Observable.Create(subj => { 
     try { 
      foreach(var v in This) { 
       subj.OnNext(v); 
      } 
      subj.OnCompleted(); 
     } catch (Exception ex) { 
      subj.OnError(ex); 
     } 

     return Disposable.Empty; 
    }); 
} 

雖然在一般,這是不是一個偉大的使用Rx的,因爲數據源是不是很容易Rx'ify - 事實上,該代碼將執行UI線程中的大部分工作,將其發送給隨機工作線程,然後將其發回(即完全浪費工作)。 Task + Dispatcher.BeginInvoke在這裏可能更適合你。

+0

感謝保羅這樣的事情應該有所幫助,我希望有一些現有的機制來處理Observable創建過程中的錯誤。我給出的例子是一個真正的減少版本,只是爲了說明問題。實際的數據檢索包括一些Interval輪詢和對外部資源的訪問(多一點Rx'y)。 – bstoney 2011-05-16 13:36:25

+0

在哪一點通常傳遞給OnError方法的異常? – bstoney 2011-05-16 14:24:42

+0

如果在枚舉序列時發生異常,它將傳遞給OnError。你看到的異常,db連接失敗,是在GetEnumerator被調用時引起的。從邏輯上講,這是在序列之外(因爲甚至沒有一個),並且異常不由Rx處理。我的建議是將你的代碼封裝在try/catch中,以分離通過數據枚舉的概念並嘗試獲取數據來枚舉。 – Lugoues 2011-06-12 18:04:41