2011-09-28 22 views
2

我写了一个程序,对通过网络摄像头传送的图像进行一些处理。每当从相机接收到新帧时都会触发事件。但是,这种情况发生得比我想要的要频繁得多,因为我的图像处理功能在新事件出现之前没有完成,并再次调用相同的函数。如何控制C#中的事件触发?

如何控制事件何时启动?我可以执行我的图像处理吗,比如每5个事件呢?我相信我已经知道了伪代码,但我更愿意在C#中看到一些示例。

+0

这伪代码将是理解你的问题有很大的帮助。 –

+0

回调函数是否需要线程安全? –

回答

2

将事件回调“守护”如下。那么它将不会同时进行多次处理。

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(); } 
    } 
} 
+0

我怀疑这个代码不是线程安全的。我对吗?? – 000

+0

@Sam正确。它认为这不是一个大问题。但你永远不知道。添加了一个线程安全版本。 – erikH

+0

我可能会锁定,而不是使用信号量......信号量不能保证线程将按照它们排队的顺序进入。 –

-1

那么你有什么伪码?我很想把它翻译成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); 
} 
-2

假设你正在使用类似的东西附加到事件:

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周期。

+4

2 downvotes和没有评论?请告诉我什么是*错误*与我的答案,所以我有机会从我的错误* *学习.. –

+0

为了弄清楚上面的逻辑是否是不好的做法,我已经打开了一个具体的问题。它位于这里:http://stackoverflow.com/questions/7594948/control-event-fireing-frequency-though-attaching-detaching-to-the-event-bad-prac –