如何使用异步方法捕获 ReactiveCommand 中的异常
How to catch exceptions in ReactiveCommand with async method
我有一个与 非常相似的问题。但是,在我的例子中,我创建了一个在执行时调用异步方法的 ReactiveCommand。 ThrownExceptions observable 似乎没有管道任何异常,无论它们被抛出在哪里(直接在方法中或在它启动的任务中)。
我写了一个最简单的例子来证明这一点。我知道 ThrownExceptions 并不能捕获所有内容,但我不知道它不适用于哪些情况或如何正确处理这些异常。
using ReactiveUI;
using System;
using System.Reactive;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main()
{
var test = new TestClass();
while (Console.ReadKey().Key == ConsoleKey.Enter)
{
test.Command.Execute().Subscribe();
}
Console.ReadKey();
}
}
public class TestClass
{
public TestClass()
{
Command = ReactiveCommand.Create(() => RunCommand());
Command.ThrownExceptions.Subscribe(ex => HandleException(ex));
}
public ReactiveCommand<Unit, Task> Command { get; private set; }
private async Task RunCommand()
{
//throw new Exception("will not be handled");
//await Task.Run(() => throw new Exception("will also not be handled"));
}
private void HandleException(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
回答我自己的问题:必须使用 CreateFromTask
方法而不是 Create
方法创建调用异步方法的命令。
此外,如果通过订阅它的 Execute
可观察命令来执行命令,则不会捕获异常。必须改用 ICommand
接口的 Execute
方法(命令应该使用此接口公开给 public)。
我已将我的演示项目更改如下:
class Program
{
static void Main()
{
var test = new TestClass();
while (Console.ReadKey().Key == ConsoleKey.Enter)
{
(test.Command as ICommand).Execute(null);
}
Console.ReadKey();
}
}
public class TestClass
{
public TestClass()
{
Command = ReactiveCommand.CreateFromTask(RunCommand);
Command.ThrownExceptions.Subscribe(ex => HandleException(ex));
}
public ReactiveCommand<Unit, Unit> Command { get; private set; }
private async Task RunCommand()
{
//throw new Exception("will be handled");
await Task.Run(() =>
{
throw new Exception("will also be handled");
});
}
private void HandleException(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
我有一个与
我写了一个最简单的例子来证明这一点。我知道 ThrownExceptions 并不能捕获所有内容,但我不知道它不适用于哪些情况或如何正确处理这些异常。
using ReactiveUI;
using System;
using System.Reactive;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main()
{
var test = new TestClass();
while (Console.ReadKey().Key == ConsoleKey.Enter)
{
test.Command.Execute().Subscribe();
}
Console.ReadKey();
}
}
public class TestClass
{
public TestClass()
{
Command = ReactiveCommand.Create(() => RunCommand());
Command.ThrownExceptions.Subscribe(ex => HandleException(ex));
}
public ReactiveCommand<Unit, Task> Command { get; private set; }
private async Task RunCommand()
{
//throw new Exception("will not be handled");
//await Task.Run(() => throw new Exception("will also not be handled"));
}
private void HandleException(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
回答我自己的问题:必须使用 CreateFromTask
方法而不是 Create
方法创建调用异步方法的命令。
此外,如果通过订阅它的 Execute
可观察命令来执行命令,则不会捕获异常。必须改用 ICommand
接口的 Execute
方法(命令应该使用此接口公开给 public)。
我已将我的演示项目更改如下:
class Program
{
static void Main()
{
var test = new TestClass();
while (Console.ReadKey().Key == ConsoleKey.Enter)
{
(test.Command as ICommand).Execute(null);
}
Console.ReadKey();
}
}
public class TestClass
{
public TestClass()
{
Command = ReactiveCommand.CreateFromTask(RunCommand);
Command.ThrownExceptions.Subscribe(ex => HandleException(ex));
}
public ReactiveCommand<Unit, Unit> Command { get; private set; }
private async Task RunCommand()
{
//throw new Exception("will be handled");
await Task.Run(() =>
{
throw new Exception("will also be handled");
});
}
private void HandleException(Exception ex)
{
Console.WriteLine(ex.Message);
}
}