C# 事件未引发和线程
本文关键字:线程 事件 | 更新日期: 2023-09-27 18:36:45
我在处理一个事件时遇到了一些麻烦。问题是有时事件只是没有引发。
我们从一家公司获得了一台相机,我们已经在我们的软件中实现了它。在软件中,我们记录了一个事件,每次在相机上拍摄图像时都会触发该事件。
我注意到,随着处理能力需求的增加(例如,计算图像的平均平均值和处理更大的图像)有时会导致事件无法引发。此外,我可以通过提高相机的帧速率来更频繁地发生这种情况。我知道缺少一个框架,因为它们标有 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
在这里会很好),以便另一个线程(或线程,如果你的处理可以安全地并行完成)可以处理项目。 但要小心,除非你只是偶尔花"太长时间"来处理事件,否则你最终可能会得到一个不断增长的队列,或者只是用超出其处理能力的线程淹没你的机器。 如果您只是偶尔花费"太长时间",那么这将有助于在不产生积压的情况下平衡它。
最后,如果处理时间太长,您可能别无选择,只能专注于提高事件处理程序的性能,使其花费的时间(平均)少于帧速率,或者只是将帧速率限制在处理可以处理的范围内。