我寫了一個程序,對通過網絡攝像頭傳送的圖像進行一些處理。每當從相機接收到新幀時都會觸發事件。但是,這種情況發生得比我想要的要頻繁得多,因爲我的圖像處理功能在新事件出現之前沒有完成,並再次調用相同的函數。如何控制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
這僞代碼將是理解你的問題有很大的幫助。 –
回調函數是否需要線程安全? –