如何从ReactiveCommand中捕获异常?

时间:2015-10-07 08:35:57

标签: c# exception exception-handling task reactiveui

我知道如何处理由ReactiveCommand<T>调用的异步任务抛出的异常,但是如何处理在返回任务之前抛出的异常?

在以下示例中,ThrowAndHandle命令将在执行时从异步任务中抛出异常,并处理异常。命令ThrowButFailToHandle表明我不能使用ThrownExceptions来处理在任务“之中”而不是在创建任务之前发生的异常。如何处理这样的例外?

public class ViewModel
{
    public IReactiveCommand ThrowAndHandle { get; private set; }
    public IReactiveCommand ThrowButFailToHandle { get; private set; }

    public ViewModel()
    {
        ThrowAndHandle = ReactiveCommand.CreateAsyncTask(_ => ThrowFromTask());
        ThrowAndHandle.ThrownExceptions.Subscribe(HandleException);

        ThrowButFailToHandle = ReactiveCommand.CreateAsyncTask(_ => ThrowBeforeTaskIsReturned());
        ThrowButFailToHandle.ThrownExceptions.Subscribe(ThisMethodWillNotBeCalled);
    }

    private Task ThrowFromTask()
    {
        return Task.Run(() => 
        {
            throw new Exception("This exception will appear in IReactiveCommand.ThrownExceptions");
        });
    }

    private Task ThrowBeforeTaskIsReturned()
    {
        throw new Exception("How can I handle this exception?");
    }

    private void HandleException(Exception ex)
    {
        // This method is called when ThrownFromTask() is called
    }

    private void ThisMethodWillNotBeCalled(Exception ex)
    {   
    }
}

1 个答案:

答案 0 :(得分:1)

假设您的命令直接绑定到UI,简短的答案是您不能。

异常将传播到ExecuteAsync observable的onError处理程序,根据Execute的实现将其忽略:

    public void Execute(object parameter)
    {
        ExecuteAsync(parameter).Catch(Observable.Empty<T>()).Subscribe();
    }

现在,如果您非常需要捕获此异常,您当然可以:

  • 将ReactiveCommand包装到ICommand中,并在出错时具有不同的Execute行为
  • 将传递给CreateAsyncCommand的lambda包装起来,以便在异常时返回失败任务结果
  • 在activeui上发布/ PR以将这些例外传播到ThrownExceptions