C# RxUi 7中视图中ThrownException交互的正确方式

C# RxUi 7中视图中ThrownException交互的正确方式,c#,xamarin.forms,system.reactive,reactiveui,C#,Xamarin.forms,System.reactive,Reactiveui,我试图理解如何在RxUi 7中使用交互来显示确认警报。读了这本书后,我想到了这个: 视图模型 public ReactiveCommand<Unit, Unit> Save { get; } public Interaction<Exception, bool> ConfirmError; Save .ThrownExceptions .Subscribe(ex => ConfirmError .Han

我试图理解如何在RxUi 7中使用
交互
来显示确认警报。读了这本书后,我想到了这个:

视图模型

public ReactiveCommand<Unit, Unit> Save { get; }
public Interaction<Exception, bool> ConfirmError;

Save
    .ThrownExceptions
    .Subscribe(ex => ConfirmError
                       .Handle(ex)
                       .Where(retry => retry == true)
                       .SelectMany(_ => Save.Execute(Unit.Default))
                       .Subscribe()
                       .AddTo(disposables))
    .AddTo(disposables);
我的代码正在工作,但我不确定确认完成后是否正确执行了命令。我还认为对于一个简单的警报框来说,代码太多了,我正在寻找一种合适的方法来实现它。 这怎么能简化呢

第二个问题是:


如果我需要处理多个
异常
类型(即:服务错误、连接错误),哪里是检查它的正确位置?

我认为您的代码基本上是正常的,除了一件事-您在另一个
订阅
中执行
订阅
调用,这在我看来是一种代码气味。为了摆脱它,你可以这样写:

Save
    .ThrownExceptions
    .SelectMany(ConfirmError.Handle)
    .Where(retry => retry == true)
    .SelectMany(_ => Save.Execute(Unit.Default))
    .Subscribe()
    .AddTo(disposables);
通过使用帮助器,可以使其更具可读性(?)

注意,我没有太多使用RXUI7.0,所以我将流更改为包含单位的流是一种猜测

我还认为对于一个简单的警报框来说,代码太多了

这是一个警报框和一个重试逻辑。我不确定你是否能在RxUI中使用比这简单得多的语言

如果我需要处理多个异常类型(即:服务错误、连接错误),那么在哪里检查它

就个人而言,我不会考虑异常类型,而是考虑与实际用户交互的方式。毕竟,您可能不想向他显示堆栈跟踪

一种方法是为与用户的不同类型的交互(
MessageInteraction
YesNoInteraction
等)提供单独的
交互
,这将允许您区分需要用户输入的操作和toast消息。另一种方法是将所有可能的问题定义为枚举(
ConnectionTimeout
servicererror
等),将可能的解决方案定义为另一个(
Retry
Abort
,…),然后在ViewModel中有一个
交互。这样,处理错误的代码将存储在一个地方。这种方法的缺点是处理逻辑在视图中,因此测试起来会困难得多


我建议您尝试一下,并报告我的想法在实践中的效果:)

效果很好。我完全误解了
SelectMany
的工作原理
InvokeCommand
也完全有意义。关于发送异常对象以查看您是对的,这一点都没有意义。En enum或类似产品可能更好。
Save
    .ThrownExceptions
    .SelectMany(ConfirmError.Handle)
    .Where(retry => retry == true)
    .SelectMany(_ => Save.Execute(Unit.Default))
    .Subscribe()
    .AddTo(disposables);
Save
    .ThrownExceptions
    .SelectMany(ConfirmError.Handle)
    .Where(retry => retry == true)
    .Select(_ => Unit.Default)
    .InvokeCommant(Save)
    .AddTo(disposables);