![](/img/trans.png)
[英]How to convert a function written using Rx Observable.FromEventPattern for event handlers to a pure .net event handler(without Rx)
[英]Using Rx Timeout with FromEventPattern Observer
我正在尝试在一段时间内没有事件的情况下实施超时。
场景:
我有一个对象,每次接收到消息时都会引发一个事件。 我想在一段时间(例如20秒)内未收到任何消息(OnReceived事件)时做出反应
这是我到目前为止
var observable = Observable.FromEventPattern<BasicDeliverEventHandler>(
handler => _innerConsumer.Received += OnReceived,
handler => _innerConsumer.Received -= OnReceived);
var timeout = observable.Timeout(TimeSpan.FromSeconds(20));
using (timeout.Subscribe(_ => { },
exception =>
Tracer.Warning("Eventing Consumer timeout : {0}", exception.Message)))
{ }
我正在从EventPattern创建一个可观察的对象。 然后,使用超时。 我不明白的是如何从超时中获取异常。 发生这种情况时,我想做出反应。
我认为Subcribe方法不是正确的方法,但是那是我从文档中得到的。 如果这不是正确的方法,我愿意提出建议或其他替代方法。
提前致谢
Timeout
是有问题的,因为它会终止序列。 Throttle
是您想要的-但是您还需要插入一个开始元素,以防万一根本没有事件发生。
我转换事件Unit.Default -当你不小心发生了什么事,只是发生了一些事情,这是有用的-并使用StartWith
种子油门:
var timeout = observable.Select(_ => Unit.Default)
.StartWith(Unit.Default)
.Throttle(TimeSpan.FromSeconds(20);
var subs = timeout.Subscribe(_ => Console.WriteLine("Timeout!"));
出于兴趣,我也有类似的解决方案来检测断开的客户端-这次为多个来源提供了一个超时通知: http : //www.zerobugbuild.com/? p= 230
让我们看看您拥有的代码。
var observable =
Observable.FromEventPattern<BasicDeliverEventHandler>(
handler => _innerConsumer.Received += OnReceived,
handler => _innerConsumer.Received -= OnReceived
);
var timeout = observable.Timeout(TimeSpan.FromSeconds(20));
using (timeout.Subscribe(
_ => { },
exception =>
Tracer.Warning("Eventing Consumer timeout : {0}", exception.Message)))
{
}
我们可以这样重写订阅逻辑:
var subscription = timeout.Subscribe(
_ => { }
exception =>
Tracer.Warning("Eventing Consumer timeout : {0}", exception.Message)
);
subscription.Dispose(); // This is bad
由于您的订阅将被立即处理,因此您的观察者不会收到您所期望的通知。
通过删除subscription.Dispose()
或using
语句,观察者在订阅20秒后应收到TimeoutException
。 但是,由于Exception
还会取消订阅,因此您只会收到一次此Exception
。
此外, Timeout
操作符在订阅时开始超时,除非取消订阅或源观察者完成,否则不会取消超时。
您可能想尝试使用其他运算符,例如Throttle
。
observable.Throttle(TimeSpan.FromSeconds(20))
.Subscribe(x =>
Console.WriteLine("it has been 20 seconds since we received the last notification.")
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.