2011-09-28 59 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 –