我会尝试解释我的问题并简化。我有一个像这样使用的Observable:
Disposable = SaveMarketDataSnapshot(dataSet).Subscribe(OnSave, OnErrorSave, OnCompletedSave);
SaveMarketDataSnapshot的定义如下:
IObservable<IMarketDataSet> SaveMarketDataSnapshot(List<IMarketDataSet> dataSet)
{
var obs = Save(data);
obs.ObserveOn(SchedulerService.UiScheduler).Subscribe(TrackSavedDataSet);//(case 1)
return obs;
}
在SaveMarketDataSnapshot中,我喜欢用于不同目的的跟踪器。
我用Observable.Create创建Observable,运行一个使用REST API调用执行Save操作的任务。
public IObservable<MarketDataSet> Save(List<KeyValuePair<string, MarketDataSet>> marketDataSet)
{
var obs = Observable.Create<MarketDataSet>(observer =>
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
Task task = new Task(() => SaveInternal(marketDataSet, observer, cancellationTokenSource.Token), cancellationTokenSource.Token);
task.Start();
return Disposable.Create(() => cancellationTokenSource.Cancel());
});
return obs;
}
void SaveInternal(List<KeyValuePair<string, MarketDataSet>> dataSets, IObserver<MarketDataSet> observer, CancellationToken cancelToken)
{
var exceptions = new List<Exception>();
try
{
foreach (var marketDataSet in dataSets)
{
try
{
throw new Exception ();//Simulate Issue
observer.OnNext(marketDataSet.Key);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
cancelToken.ThrowIfCancellationRequested();
}
if (exceptions.Count > 0)
{
AggregateException aggExcep = new AggregateException(
"Encountered errors while saving marlket data ",
exceptions);
observer.OnError(aggExcep);
}
else
{
observer.OnCompleted();
}
}
}
SaveMarketDataSet是一个外部服务
void SaveMarketDataSet(MarketDataSet, string)
在我的一个测试中,我在运行任务(REST API调用)中遇到异常。幸运的是,我很好地捕获了异常并调用了observer.OnError(ex)
问题在于,当我得到第一个异常时,我的应用程序终止,没有任何异常。经过不同的测试,我了解到TrackSavedDataSet是我崩溃的根源。
我可以通过向我的订阅添加OnError委托来解决问题,但我想了解问题的根源。 我替换旧的订阅(案例2):
obs.Subscribe(TrackSavedDataSet);
在这种情况下,没有任何事情发生,甚至我的其他订阅的OnErrorSave也没有运行。
最后我用(案例3)替换我的电话:
obs.SubscribeOn(SchedulerService.NewTaskScheduler).
Subscribe(TrackSavedDataSet);
在这种情况下,调用OnErrorSave并获得UnobservedTaskException。
我认为这个问题的根源是没有处理第二个观察者的OnError并且重新抛出异常。
我有这个假设来解释这3个行为:
案例1:在UI线程中抛出异常并停止应用程序?
案例2:异常抛出用于运行observable的同一个任务,这甚至打破了第一个订阅OnError通知?
案例3:在运行observable(SchedulerService.NewTaskScheduler)的Task中抛出异常而没有catch被认为是未观察到的?
可以请某人澄清这些行为吗?