Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用FromEventPattern Observer的Rx超时_C#_Events_Timeout_System.reactive - Fatal编程技术网

C# 使用FromEventPattern Observer的Rx超时

C# 使用FromEventPattern Observer的Rx超时,c#,events,timeout,system.reactive,C#,Events,Timeout,System.reactive,我试图在一段时间内没有事件时实现超时 情景: 我有一个对象,它在每次收到消息时引发一个事件。 我希望在一段时间内(比如20秒)没有收到任何消息(OnReceived事件)时做出反应 这就是我目前所拥有的 var observable = Observable.FromEventPattern<BasicDeliverEventHandler>( handler => _innerConsumer.Received +=

我试图在一段时间内没有事件时实现超时

情景:

我有一个对象,它在每次收到消息时引发一个事件。 我希望在一段时间内(比如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)))
{ }
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
在这种情况下不起作用,因为没有要抑制的事件。