【问题标题】:How to check if an event was raised or not within a particular time frame?如何检查事件是否在特定时间范围内引发?
【发布时间】:2011-12-21 20:16:28
【问题描述】:

我在 .Net4.0 上使用 C++CLI 编写应用程序我有一个事件处理程序,用于处理可以在任何随机时间引发的事件 该事件仅在特定时间范围内发生(或应在一个时间段内发生一次)时才有用 我需要检查事件是否在过去的时间间隔内引发过一次。如果它没有在特定的时间间隔内引发,我将引发异常。

我试过这样实现它:

  1. 为类添加一个布尔标志变量
  2. 在事件处理程序中,设置 标志=真
  3. 要进行检查,我有一个计时器事件:
  4. 每 200 毫秒触发一次计时器事件
  5. 检查标志是否为真
  6. 如果是 true 它将计数器设置为 0
  7. 定时器事件然后将标志设置为假
  8. 如果发现标志为假,则增加一个计数器
  9. 如果计数器已达到限制(例如三个),则会引发异常。

但是我发现它给出了误报。 Thios 可能是因为事件被阻止或其他原因而发生的?

有人知道更好的方法吗?我想知道是否有某种方法可以在没有外部计时器事件(或线程)的情况下做到这一点,因为它可能会中断其他线程。

提前致谢。

【问题讨论】:

  • 我不确定我的评论是否可以帮助您,但您是否尝试让事件处理程序在构造函数上创建带有static 标志的static 检查器类的对象?每个对象创建过程都会增加静态标志。然后您可以比较标志的值和时间范围。

标签: .net multithreading events c++-cli


【解决方案1】:

不确定你的 c++CLI 的含义,但是当我在 C# 中对异步事件进行单元测试时,我通常会这样做:

    [Test]
    public void CheckThatEventIsRaisedWithinTimeframe()
    {
        var eventRaised = new ManualResetEvent(false);
        subject.SomeEvent += (s, e) => { eventRaised.Set(); };

        // Do something which should have triggered the event

        Assert.True(eventRaised.WaitOne(5000), "Event was not raised.");
    }

WaitOne 调用将阻塞,直到时间用完(在本例中为 5 秒)或引发事件。在第一种情况下,WaitOne 将返回 false,在第二种情况下,它将返回 true。

我假设你可以做类似的事情,例如:

var eventRaised = new AutoResetEvent(false);
subject.SomeEvent += (s, e) => { eventRaised.Set(); };

while(true)
{
    var ok = eventRaised.WaitOne(5000);
    if(!ok)
         throw new Exception("Event was not raised for 5 seconds");
}

如果事件没有至少每 5 秒引发一次,这应该会继续运行并引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2020-07-28
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    相关资源
    最近更新 更多