2011-01-20 151 views
0

我有一個關於基於事件的程序性能的問題。我公司的 我們有一個交易清單。通過一些更改來處理它們,我們有一個計時器,它可以喚醒每個時間間隔並運行列表中的所有對象並檢查數據。 我想將其改爲事件庫。但我擔心表現。例如我有1000個事務與1000個「日誌」事件句柄將是不夠的效率? 感謝您的任何答案。 G基於事件的程序

- 編輯: 可以說你有1000個A類對象,而A類有屬性時間創建。 現在當時間創建大於一小時時,我們想要從列表中刪除對象。到目前爲止,我們使用了一個計時器,它在整個列表中每15分鐘運行一次,以檢查創建時間是否大於一小時。但我們可以創建一個事件來做到這一點...但註冊1000,並且可能是十個偶數事件處理程序影響程序的時間。所以我的問題是,這是一個好的和有效的編程?

+1

沒有足夠的信息來開始猜測。這是不可能回答的。 – Oded 2011-01-20 22:19:12

+0

我同意@dem,這個問題很難對我們負責。它取決於很多事情,唯一可能的答案是:是的,如果做得對,它會很有效率。 – Bobby 2011-01-20 22:20:53

回答

2

您可以考慮使用類似於您已有的生產者/消費者模型,而不是基於事件的體系結構。但不是在一段時間內醒來,而是使用BlockingCollection作爲隊列。

當事務進入時,只需將其添加到隊列中即可。

程序中的單獨線程位於循環中,該循環從隊列中執行TryTake(),並具有無限等待超時。無論何時將事務添加到隊列中,該線程都會獲取並處理它,然後返回到下一個。您處理線程的主循環將類似於此:

// Initialized at program startup. 
BlockingCollection<Transaction> queue = new BlockingCollection<Transaction>(); 

// In your thread proc 
Transaction trans; 

while (queue.TryTake(out trans, Timeout.Infinite)) 
{ 
    // process transaction 
} 
// Collection is empty 

TryTake是一個非忙等待,所以它不會吃的CPU週期。

這應該比基於事件的系統更容易實現,並提供更好的性能。您也不必擔心導致問題的併發事件太多。隊列將緩衝事件,以便儘可能快地處理事務。如果您需要/希望,它還可以讓您創建多個消費者。

例如,要求:

例如,以上面的代碼,並把它變成一個線程PROC:

private void TransactionConsumer() 
{ 
    Transaction trans; 
    while (queue.TryTake(out trans, Timeout.Infinite)) 
    { 
     // process transaction 
    } 
    // Collection is empty 
} 

還假設您有將東西添加到一些其他的方法隊列。我們會打電話給TransactionProducer。你的主要程序啓動三個線程:生產者和兩位消費者:

Thread producer = new Thread(TransactionProducer); 
Thread consumer1 = new Thread(TransactionConsumer); 
Thread consumer2 = new Thread(TransactionConsumer); 

producer.Start(); 
consumer1.Start(); 
consumer2.Start(); 

// At this point, you are processing transactions. 
// The main thread waits for all threads to exit. 
producer.Join(); 
consumer1.Join(); 
consumer2.Join(); 

請注意,如果實際處理事務的方法使用共享資源(像一個普通的日誌文件),那麼你就必須保護那些與一些一種同步(也許是一個鎖)。