2011-05-16 73 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