Linq to sql 使用Linq到SQL和Rx处理数据库连接异常

Linq to sql 使用Linq到SQL和Rx处理数据库连接异常,linq-to-sql,system.reactive,Linq To Sql,System.reactive,我正在尝试学习如何最好地使用被动扩展库,并设置了简单的测试WPF应用程序来查看日志数据库表。在ViewModel类中,我使用从Linq到Sql的前100个日志条目填充ObservableCollection,并尝试使用Rx保持UI响应 除非数据库不可用,否则以下代码段将正常工作,此时应用程序将抛出异常并崩溃。处理数据库连接异常的最佳位置是哪里?为什么不使用观察者的OnError方法来处理它们 ObservableCollection<LogEntry> _logEntries = n

我正在尝试学习如何最好地使用被动扩展库,并设置了简单的测试WPF应用程序来查看日志数据库表。在ViewModel类中,我使用从Linq到Sql的前100个日志条目填充
ObservableCollection
,并尝试使用Rx保持UI响应

除非数据库不可用,否则以下代码段将正常工作,此时应用程序将抛出异常并崩溃。处理数据库连接异常的最佳位置是哪里?为什么不使用观察者的
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() ) );
ObservableCollection\u logEntries=新的ObservableCollection();
DataContext DataContext=新的DataContext(“连接字符串”);
(来自dataContext.LogEntries中的e)
选择e).Take(100).ToObservable()
.SubscribeOn(Scheduler.ThreadPool)
.ObserveOnDispatcher()
.Subscribe(_logEntries.Add,ex=>System.Diagnostics.Debug.WriteLine(ex.ToString());

请尝试此操作,而不要使用可观察的:

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;
    });
}
public static IObservable safetobservable(this IEnumerable this)
{
返回可观察的。创建(subc=>{
试一试{
foreach(本文件中的var v){
subject.OnNext(v);
}
subc.OnCompleted();
}捕获(例外情况除外){
主体一人(ex);
}
返回一次性。空;
});
}

不过,一般来说,这并不是Rx的一个很好的用途,因为数据源不容易Rx’ify——事实上,代码将在UI线程上执行大部分工作,将其发送到随机工作线程,然后再发送回来(即完全浪费的工作)。Task+Dispatcher.BeginInvoke可能更适合您。

谢谢Paul,这样做应该会有所帮助,我希望在可观察创建过程中有一些现有的机制来处理错误。我给出的例子是一个真正简化的版本,只是为了说明这个问题。实际的数据检索包括一些间隔轮询和对外部资源的访问(稍微多一点)。异常通常在哪一点传递给OnError方法?如果在枚举序列时发生异常,它将传递给OnError。您看到的异常db connection failed是在调用GetEnumerator时引起的。从逻辑上讲,这是在序列之外的(因为甚至没有序列),并且异常不由Rx处理。我的建议是将代码包装成try/catch,以分离通过数据枚举的概念和试图获取要枚举的数据的概念。