RX.Net:使用重试但记录任何异常
RX.Net : Use Retry but log any Exception
我是RX的新手,一直在研究错误处理和重试的使用;我有以下内容(是的,我知道这不是 'real' 单元测试,但它让我可以进入 fiddle!!)并且想知道我如何继续保持重试但能够记录任何异常?
[Test]
public void Test()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateHotObservable(
new Recorded<Notification<long>>(10000000, Notification.CreateOnNext(0L)),
new Recorded<Notification<long>>(20000000, Notification.CreateOnNext(1L)),
new Recorded<Notification<long>>(30000000, Notification.CreateOnNext(2L)),
new Recorded<Notification<long>>(30000001, Notification.CreateOnError<long>(new Exception("Fail"))),
new Recorded<Notification<long>>(40000000, Notification.CreateOnNext(3L)),
new Recorded<Notification<long>>(40000000, Notification.CreateOnCompleted<long>())
);
source.Retry().Subscribe(
l => Console.WriteLine($"OnNext {l}"),
exception => Console.WriteLine(exception.ToString()), // Would be logging this in production
() => Console.WriteLine("OnCompleted"));
scheduler.Start(
() => source,
0,
TimeSpan.FromSeconds(1).Ticks,
TimeSpan.FromSeconds(5).Ticks);
}
这导致...
OnNext 0
OnNext 1
OnNext 2
OnNext 3
OnCompleted
...这正是我想要发生的事情,除了我想记录发生在 2 和 3 之间的异常之外。
有没有办法允许订阅者在 OnError 中看到异常(并记录它)然后重新订阅以便它看到 3?
谢谢!
你可以这样实现:
source
.Do(_ => { }, exception => Console.WriteLine(exception.ToString()), () => {})
.Retry()
.Subscribe(
l => Console.WriteLine($"OnNext {l}"),
// exception => Console.WriteLine(exception.ToString()), // Would be logging this in production
() => Console.WriteLine("OnCompleted")
);
只是为了澄清这里发生了什么:OnError
是一个终止信号。如果错误到达订阅,那将终止流的其余部分。 .Retry
终止订阅,吞下 OnError
,然后重新订阅,将两个订阅融合在一起。例如看这个:
source
.StartWith(-1)
.Retry()
.Subscribe(
l => Console.WriteLine($"OnNext {l}"),
() => Console.WriteLine("OnCompleted")
);
你的输出将是
OnNext -1
OnNext 0
OnNext 1
OnNext 2
OnNext -1
OnNext 3
OnCompleted
OnNext -1
出现两次,因为它会在您订阅时出现(Retry
在 OnError
之后出现。
坦率地说,您的测试 observable 是一个糟糕的测试。它打破了 "Rx Contract",即通知遵循以下模式:
OnNext* (OnCompleted | OnError)?
即 0 条或更多条 OnNext
条通知,后跟可选的 OnError
或可选的 OnCompleted
。任何类型的通知都不应跟在 OnError
或 OnCompleted
.
之后
我是RX的新手,一直在研究错误处理和重试的使用;我有以下内容(是的,我知道这不是 'real' 单元测试,但它让我可以进入 fiddle!!)并且想知道我如何继续保持重试但能够记录任何异常?
[Test]
public void Test()
{
var scheduler = new TestScheduler();
var source = scheduler.CreateHotObservable(
new Recorded<Notification<long>>(10000000, Notification.CreateOnNext(0L)),
new Recorded<Notification<long>>(20000000, Notification.CreateOnNext(1L)),
new Recorded<Notification<long>>(30000000, Notification.CreateOnNext(2L)),
new Recorded<Notification<long>>(30000001, Notification.CreateOnError<long>(new Exception("Fail"))),
new Recorded<Notification<long>>(40000000, Notification.CreateOnNext(3L)),
new Recorded<Notification<long>>(40000000, Notification.CreateOnCompleted<long>())
);
source.Retry().Subscribe(
l => Console.WriteLine($"OnNext {l}"),
exception => Console.WriteLine(exception.ToString()), // Would be logging this in production
() => Console.WriteLine("OnCompleted"));
scheduler.Start(
() => source,
0,
TimeSpan.FromSeconds(1).Ticks,
TimeSpan.FromSeconds(5).Ticks);
}
这导致...
OnNext 0
OnNext 1
OnNext 2
OnNext 3
OnCompleted
...这正是我想要发生的事情,除了我想记录发生在 2 和 3 之间的异常之外。
有没有办法允许订阅者在 OnError 中看到异常(并记录它)然后重新订阅以便它看到 3?
谢谢!
你可以这样实现:
source
.Do(_ => { }, exception => Console.WriteLine(exception.ToString()), () => {})
.Retry()
.Subscribe(
l => Console.WriteLine($"OnNext {l}"),
// exception => Console.WriteLine(exception.ToString()), // Would be logging this in production
() => Console.WriteLine("OnCompleted")
);
只是为了澄清这里发生了什么:OnError
是一个终止信号。如果错误到达订阅,那将终止流的其余部分。 .Retry
终止订阅,吞下 OnError
,然后重新订阅,将两个订阅融合在一起。例如看这个:
source
.StartWith(-1)
.Retry()
.Subscribe(
l => Console.WriteLine($"OnNext {l}"),
() => Console.WriteLine("OnCompleted")
);
你的输出将是
OnNext -1
OnNext 0
OnNext 1
OnNext 2
OnNext -1
OnNext 3
OnCompleted
OnNext -1
出现两次,因为它会在您订阅时出现(Retry
在 OnError
之后出现。
坦率地说,您的测试 observable 是一个糟糕的测试。它打破了 "Rx Contract",即通知遵循以下模式:
OnNext* (OnCompleted | OnError)?
即 0 条或更多条 OnNext
条通知,后跟可选的 OnError
或可选的 OnCompleted
。任何类型的通知都不应跟在 OnError
或 OnCompleted
.