这里是一个什么我试图证明(以上)的简化版本:在执行低级ReactiveCommands时,ReactiveUI如何处理异常?
var reactiveCommandA = ReactiveCommand.CreateAsyncTask(_ => CanPossiblyThrowAsync());
reactiveCommandA.ThrownExceptions
.Subscribe(ex => UserError.Throw("Oh no A", ex));
var reactiveCommandB = ReactiveCommand.CreateAsyncTask(_ => CanAlsoPossiblyThrowAsync());
reactiveCommandB.ThrownExceptions
.Subscribe(ex => UserError.Throw("Oh no B", ex));
var reactiveCommandC = ReactiveCommand.CreateAsyncTask
(
async _ =>
{
await reactiveCommandA.ExecuteAsync(); // <= Could throw here
await reactiveCommandB.ExecuteAsync();
DoSomethingElse();
}
);
reactiveCommandC.ThrownExceptions
.Subscribe(ex => UserError.Throw("Oh no C", ex));
所以假设我的背景,实施reactiveCommandA
可能会抛出异常。这没关系,因为我订购了.ThrownExceptions
,理论上会通知用户并重试/失败/中止(为简洁起见,此处未显示)。所以它不会冒泡给调度员。
所以当reactiveCommandA
被自己执行时,这是很棒的。但是,我有reactiveCommandC
它执行reactiveCommandA
和reactiveCommandB
。我也订阅了它的.ThrownExceptions
。我遇到的问题是,如果我执行reactiveCommandC
和reactiveCommandA
实现抛出它,它也导致reactiveCommandC
炸毁。然后我通知用户两次相同的根错误,因为reactiveCommandA
做它的.ThrownExceptions
事情,然后reactiveCommandC
做它的.ThrownExceptions
事情。
那么是否有这种类型的情况的标准方法?最好是有点优雅,因为我发现现有的代码相当干净,我不想混乱或引入意大利面条。
事情我已经想到了:
,围绕着
try/catch
块“的await ......”线和吞咽异常和退出。如果我必须做很多,看起来很丑。使用
await reactiveCommandA.ExecuteAsync().Catch(Observable.Never<Unit>());
虽然我认为这会导致reactiveCommandC永远不会完成,因此它永远不会再执行。使用与方法相同的方法,但根据我是否顺利过关成功与否(如
.Catch(Observable.Return(false))
。仍然要检查,如果我们可以在每个await
语句之间继续返回一个布尔值。
有什么雨衣在这里做的感谢
很公平,保罗。虽然不是一个超级满意的答案,但我很高兴它将在未来得到改进,我也很高兴知道我没有错过某些明显的东西。我将继续看到RxUI如何继续发展。 – 2014-10-07 16:14:29