C#事件没有引发和线程

时间:2013-10-23 14:11:22

标签: c# multithreading events

我在活动中遇到了一些麻烦。问题是有时事件不会被提出。

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

我注意到随着处理能力需求的增加(例如计算图像上的平均均值和处理更大的图像),有时会导致事件没有被提升。此外,我可以通过提高相机的帧速率来更频繁地实现这一点。我知道帧丢失了,因为它们标有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));
        }
    }
}

正如您所看到的,我将框架添加到队列中,然后告诉我的外部类,它们可以获取它们。我正在尽快发布活动主题。

要点:

我的活动有时候没有提出。我认为这是因为主线程工作太辛苦了。

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

1 个答案:

答案 0 :(得分:13)

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

你可以通过拥有一个实际上没有完成工作的事件处理程序来解决这个问题,而是将信息放入一个队列(这里BlockingCollection会很好),这样另一个线程(或线程,如果您的处理可以安全地并行处理)可以处理项目。但要小心,除非你偶尔花费太长时间来处理事件,否则你最终会得到一个只会增长和增长的队列,或者只是使用比它可以处理的线程更多的线程来淹没你的机器。如果你只是偶尔采取“太长时间”,那么这将有助于在没有创建积压的情况下解决问题。

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