我在处理一个事件时遇到了一些问题。问题是有时事件不会引发。
我们从一家公司得到了一台相机,我们已经在我们的软件中实现了它。在软件中,我们注册了一个事件,每次在相机上拍摄图像时都会触发该事件。
我注意到随着处理能力需求的增加(例如,计算图像的平均平均值和处理更大的图像)有时会导致事件不被触发。此外,我可以通过增加相机的帧速率来使这种情况更频繁地发生。我知道缺少一个框架,因为它们标有 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));
}
}
}
如您所见,我获取了框架,将其添加到队列中,然后告诉我的外部类他们需要获取一些内容。我会尽快释放事件线程。
总结:
我的事件有时不会引发。我认为这是因为主线程工作太辛苦了。
您是否有过有时不引发事件的经验?
最佳答案
在触发事件的代码能够触发更多事件之前,事件处理程序都需要完成;它可能只有一个线程来触发事件。当它在当前事件完成之前有一个新事件要触发时,它可以跳过触发该事件(这似乎是这样做的)或将其排队以备后用。如果它执行后者,那么如果事件处理程序几乎总是花费比事件触发之间的时间更长的时间,它就会冒着真正远远落后的风险。落后意味着消耗的内存量不断增加,以及为很久以前发生的事情触发事件,这(在某些情况下)可能是个问题。
你可以自己解决这个问题,方法是让一个事件处理程序实际上不执行工作,而是将信息放入队列(BlockingCollection
在这里会很好),以便另一个线程(或线程,如果您的处理可以安全地并行完成)可以处理项目。但是要小心,除非你只是偶尔花“太长时间”来处理事件,否则你最终可能会得到一个不断增长的队列,或者只是让你的机器充满了超过它可以处理的线程。如果您只是偶尔花“太长时间”,那么这将有助于平衡它,而不会产生积压。
最后,如果您的处理时间太长,您可能别无选择,只能专注于提高事件处理程序的性能,使其花费的时间(平均)少于帧速率,或者只是限制帧速率到您的处理可以处理的范围。
关于C# 事件未引发和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19544139/