C# 使用FromEventPattern Observer的Rx超时
我试图在一段时间内没有事件时实现超时 情景: 我有一个对象,它在每次收到消息时引发一个事件。 我希望在一段时间内(比如20秒)没有收到任何消息(OnReceived事件)时做出反应 这就是我目前所拥有的C# 使用FromEventPattern Observer的Rx超时,c#,events,timeout,system.reactive,C#,Events,Timeout,System.reactive,我试图在一段时间内没有事件时实现超时 情景: 我有一个对象,它在每次收到消息时引发一个事件。 我希望在一段时间内(比如20秒)没有收到任何消息(OnReceived事件)时做出反应 这就是我目前所拥有的 var observable = Observable.FromEventPattern<BasicDeliverEventHandler>( handler => _innerConsumer.Received +=
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 observable=observable.FromEventPattern(
handler=>\u innerConsumer.Received+=OnReceived,
handler=>\u innerConsumer.Received-=OnReceived);
var timeout=可观察的超时(TimeSpan.FromSeconds(20));
使用(timeout.Subscribe(=>{}),
异常=>
Tracer.Warning(“事件使用者超时:{0}”,exception.Message)))
{ }
我正在从事件模式创建一个可观察的。然后,使用超时。我不明白的是如何从超时中获取异常。我想在这种情况发生时做出反应
我不认为Subcribe方法是正确的方法,但这是我从文档中得到的。
如果这不是正确的,我愿意接受建议或其他选择
提前感谢让我们看看您的代码
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)))
{
}
由于您的订阅将被立即处理,因此您的观察者不会收到您期望的通知
通过删除subscription.Dispose()
,或使用语句删除,您的观察者应在订阅后20秒收到TimeoutException
。但是,由于Exception
s也会取消订阅,因此您只能收到此Exception
一次
此外,Timeout
操作符在订阅时启动超时,并且不会取消超时,除非订阅被取消,或者源观察者完成
您可能需要尝试使用不同的操作符,例如油门
observable.Throttle(TimeSpan.FromSeconds(20))
.Subscribe(x =>
Console.WriteLine("it has been 20 seconds since we received the last notification.")
)
让我们看看你的代码
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)))
{
}
由于您的订阅将被立即处理,因此您的观察者不会收到您期望的通知
通过删除subscription.Dispose()
,或使用语句删除,您的观察者应在订阅后20秒收到TimeoutException
。但是,由于Exception
s也会取消订阅,因此您只能收到此Exception
一次
此外,Timeout
操作符在订阅时启动超时,并且不会取消超时,除非订阅被取消,或者源观察者完成
您可能需要尝试使用不同的操作符,例如油门
observable.Throttle(TimeSpan.FromSeconds(20))
.Subscribe(x =>
Console.WriteLine("it has been 20 seconds since we received the last notification.")
)
超时
有问题,因为它会终止序列Throttle
是您想要的,但是您还需要插入一个start元素,以防根本没有事件发生
我将事件转换为Unit.Default(单位默认值)—这在您不关心发生了什么,只关心发生了什么的情况下非常有用—并使用StartWith
为油门设定种子:
var timeout = observable.Select(_ => Unit.Default)
.StartWith(Unit.Default)
.Throttle(TimeSpan.FromSeconds(20);
var subs = timeout.Subscribe(_ => Console.WriteLine("Timeout!"));
出于兴趣,我还有一个类似的解决方案用于检测断开连接的客户端-这次为多个源提供一个超时通知:超时
是有问题的,因为它会终止序列Throttle
是您想要的,但是您还需要插入一个start元素,以防根本没有事件发生
我将事件转换为Unit.Default(单位默认值)—这在您不关心发生了什么,只关心发生了什么的情况下非常有用—并使用StartWith
为油门设定种子:
var timeout = observable.Select(_ => Unit.Default)
.StartWith(Unit.Default)
.Throttle(TimeSpan.FromSeconds(20);
var subs = timeout.Subscribe(_ => Console.WriteLine("Timeout!"));
出于兴趣,我还有一个类似的解决方案用于检测断开连接的客户端-这次为多个源提供一个超时通知:在代码中不应该有using
语句。这将立即取消您的订阅,这将阻止您的任何通知到达观察者。您的代码中不应该有using
语句。这将立即取消您的订阅,这将阻止您的任何通知到达观察者。我正在考虑将StartWith
添加到我的答案中,但作为消费者,我希望获得原始事件。我想这取决于消费者使用数据的确切方式。OP没有要求它,但您可以始终使用空对象作为种子,例如EventArgs.Empty
。我没有在StartWith前后得到讨论。我想杀人the@Markust你能换个说法吗?我不明白。StartWith是必需的,这样在根本没有引发任何事件的情况下流将超时-节流阀在这种情况下不起作用,因为没有要抑制的事件。我正在考虑将StartWith
添加到我的答案中,但作为消费者,我想要原始事件。我想这取决于消费者使用数据的确切方式。OP没有要求它,但您可以始终使用空对象作为种子,例如EventArgs.Empty
。我没有在StartWith前后得到讨论。我想杀人the@Markust你能换个说法吗?我不明白。StartWith是必需的,这样在根本没有引发任何事件的情况下,流将超时-Throttle
在这种情况下不起作用,因为没有要抑制的事件。