【问题标题】:C# Event not raised and ThreadsC# 事件未引发和线程
【发布时间】:2013-10-23 14:11:21
【问题描述】:

我在参加某个活动时遇到了一些问题。问题是有时事件并没有引发。

我们已经在我们的软件中实施了来自一家公司的相机。在软件中,我们注册了一个事件,每次在相机上拍摄图像时都会触发该事件。

我注意到,随着处理能力需求的增加(例如计算图像的平均平均值和处理更大的图像),有时会导致事件不被引发。此外,我可以通过提高相机的帧速率来更频繁地实现这一点。我知道缺少一个框架,因为它们标有 ID。

在他们自己的演示软件中,我能够以相同的速度运行,没有任何问题。他们的软件不执行任何计算或任何操作,它只是接收并显示图像。

我很困惑,因为这是与我所拥有的相机最近的连接;我所能做的就是等待事件发生。我想问一下您是否知道任何会忽略事件的情况。

在我看来,摄像头正在拍摄图像,但由于某种原因,事件没有拾取(过载?)。

以下是一些相关代码:

private void Camera_OnFrameReceived(AVT.VmbAPINET.Frame frame)
{
    if (frame.ReceiveStatus == VmbFrameStatusType.VmbFrameStatusComplete)
    {
        if (lastID != 0 && lastID != 1)
        {
            if(frame.FrameID - lastID > 1)
                Debug.WriteLine("HEEEEYYY SKIPPED A FRAME, ID: " + frame.FrameID.ToString() + " TOTAL LOST: " + (frame.FrameID - lastID - 1).ToString());
        }
        lastID = frame.FrameID;
        //Debug.WriteLine("Frame received from camera");

        //if the camera is in single mode, dont raise the event (frame already taken)
        if (Mode == CaptureMode.Single)
            return;

        //set the last frame
        _frameQueue.Enqueue(frame);

        if (FilmFrameReady != null)
        {
            DateTime dateTime = Accurate.DtNow;
            frameTaken = false;
            FilmFrameReady(this, new FilmFrameReadyArgs(this, dateTime));
        }
    }
}

如您所见,我获取了框架,将其添加到队列中,然后告诉我的外部类有一些东西要获取。我正在尽快发布事件线程。

总结:

我的事件有时不会引发。我想是因为主线程工作太辛苦了。

您是否有任何事件有时不被提出的经验?

【问题讨论】:

  • 这听起来像是您正在使用的第 3 方库而不是您的代码的问题。但是,如果您可以显示一些代码,这将是一个开始...
  • 我也是这样,直到我开始他们的演示程序并且它运行良好。我已经包含了一些代码

标签: c# multithreading events


【解决方案1】:

在触发事件的代码能够触发更多事件之前,所有事件处理程序都需要完成;它可能只有一个线程来触发事件。当它在当前事件完成之前有一个新事件要触发时,它可以跳过触发该事件(这似乎是这样做的)或将其排队以备后用。如果是后者,如果事件处理程序几乎总是花费比事件触发之间的时间更长的时间,那么它就有可能远远落后。落后意味着消耗的内存量不断增加,而且事件会因为很久以前发生的事情而被触发,这(在某些情况下)可能是一个问题。

您可以自己解决这个问题,方法是让事件处理程序实际上不执行工作,而是将信息放入队列(BlockingCollection 在这里会很好),以便另一个线程(或多个线程,如果您的处理可以安全地并行完成)可以处理项目。但是要小心,除非您只是偶尔花费“太长时间”来处理事件,否则您最终可能会遇到一个不断增长的队列,或者只是让您的机器充满超出其处理能力的线程。如果您只是偶尔花费“太长时间”,那么这将有助于解决问题而不会造成积压。

最后,如果您的处理时间太长,您可能别无选择,只能专注于提高事件处理程序的性能,使其(平均)花费的时间少于帧速率,或者只是限制帧速率达到您的处理能力。

【讨论】:

  • 抱歉,我应该包含一些代码。正如您在我编辑的问题中看到的那样,我正在尽快发布线程。
  • 你似乎仍然是对的。在每次错过一帧之前,该函数需要 0.2-0.3 秒才能完成,而不是正常的 0.032-0.003 秒。我猜这与我从未包含在编辑代码“Camera.QueueFrame(frame);”中的部分有关我再次将接收到的帧添加到相机队列中。不过,我将不得不检查一下。
猜你喜欢
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多