我写了一个程序,对通过网络摄像头传送的图像进行一些处理。每当从相机接收到新帧时都会触发事件。但是,这种情况发生得比我想要的要频繁得多,因为我的图像处理功能在新事件出现之前没有完成,并再次调用相同的函数。如何控制C#中的事件触发?
如何控制事件何时启动?我可以执行我的图像处理吗,比如每5个事件呢?我相信我已经知道了伪代码,但我更愿意在C#中看到一些示例。
我写了一个程序,对通过网络摄像头传送的图像进行一些处理。每当从相机接收到新帧时都会触发事件。但是,这种情况发生得比我想要的要频繁得多,因为我的图像处理功能在新事件出现之前没有完成,并再次调用相同的函数。如何控制C#中的事件触发?
如何控制事件何时启动?我可以执行我的图像处理吗,比如每5个事件呢?我相信我已经知道了伪代码,但我更愿意在C#中看到一些示例。
将事件回调“守护”如下。那么它将不会同时进行多次处理。
private bool m_active;
void YourCallback(object sender, EventArgs args)
{
if(!m_active)
{
try
{
m_active = true;
// Do the work here...
}
finally { m_active = false; }
}
}
编辑:线程安全如果使用f.i. Semaphore。
private System.Threading.Semaphore m_Semaphore = new System.Threading.Semaphore(0, 1);
void YourCallback(object sender, EventArgs args)
{
if(m_Semaphore.WaitOne(0))
{
try
{
// Do the work here...
}
finally { m_Semaphore.Release(); }
}
}
那么你有什么伪码?我很想把它翻译成C#。 ;-)
您可以使用一个DateTime变量来存储事件的最后一个事件,如果小于预期的时间,则跳过该事件。
所以,这样的事情,如果你想要的工作,一旦第二,不管它有多少次被解雇:
private DateTime _lastEvent = DateTime.Now;
public void Event()
{
if (_lastEvent + new TimeSpan(0, 0, 1) > DateTime.Now)
return;
_lastEvent = DateTime.Now;
// Now do your event
Console.WriteLine("Tick! " + _lastEvent);
}
假设你正在使用类似的东西附加到事件:
public MyObject()
{
MyImageObject.Update += new UpdateEventHandler(ImageDataUpdated);
}
private void ImageDataUpdated(object sender, EventArgs e)
{
// do stuff
}
您可以在事件处理程序的开始处从事件中分离,然后在一定的时间间隔后使用timer重新附加。这会让你对更新率有一个精确的控制。喜欢的东西:
public MyObject()
{
MyTimer = new System.Timers.Timer(100); // 10 Hz
MyTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
MyTimer.Enabled = true;
}
private void ImageDataUpdated(object sender, EventArgs e)
{
// detach from the event to keep it from fireing until the timer event has fired.
MyImageObject.Update -= new UpdateEventHandler(ImageDataUpdated);
// do stuff
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
// (re-)attach to the event handler.
MyImageObject.Update += new UpdateEventHandler(ImageDataUpdated);
}
使用这种策略有,你是防止潜在的图像对象,而事件处理程序分开做额外的工作奠定了良好的变化(当然这取决于图像对象的实现)。有可能你正在为自己的图像处理节省CPU周期。
2 downvotes和没有评论?请告诉我什么是*错误*与我的答案,所以我有机会从我的错误* *学习.. –
为了弄清楚上面的逻辑是否是不好的做法,我已经打开了一个具体的问题。它位于这里:http://stackoverflow.com/questions/7594948/control-event-fireing-frequency-though-attaching-detaching-to-the-event-bad-prac –
你可以使用IObservable.SkipWhile跳过事件到达您的处理程序,而你的图像处理正在发生的事情。
这个问题有一个类似的问题:
Filtering a Touch.FrameReported IObservable using arbitrary boolean condition that changes over time
这伪代码将是理解你的问题有很大的帮助。 –
回调函数是否需要线程安全? –