i have a question about event based program performance. in my company we have a list of transactions. to deal with them by some changes we have a timer that wakes up every interval and run on all the objects in the list and checks the data. i want to change it to event bases. but i worry about performance. for example i have 1000 transactions with 1000 "log" to event handles will it be unefficient ? thanks for any answer. G
--edit: lets say you have 1000 objects of a class A. and class A have the property time creation. now when time creation is larger then an hour we want to erase the object from the list. until now we used a timer that run every 15 minutes on the entire list to check that the creation time is larger then an hour. but we can create an event to do that... but registering 1000 and can be times ten even events handlers have affect on the programs. so my qeuestion is , is this开发者_StackOverflow社区 good and efficient programming?
Rather than an event-based architecture, you might consider using a producer/consumer model similar to what you already have. But instead of waking up on an interval, use a BlockingCollection
as a queue.
When a transaction comes in, just add it to the queue.
A separate thread in your program sits in a loop that does a TryTake()
from the queue, with an infinite wait timeout. Whenever a transaction is added to the queue, this thread will get and process it, then go back for the next one. Your processing thread's main loop would look similar to this:
// 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
The TryTake
is a non-busy wait, so it won't be eating CPU cycles.
This should be much easier to implement than an event-based system, and provide better performance. You also don't have to worry about too many concurrent events causing a problem. The queue will buffer things so that you can process transactions as fast as possible. It also would let you create multiple consumers if you need/want to.
Example, as requested:
For example, take the code above and put it into a thread proc:
private void TransactionConsumer()
{
Transaction trans;
while (queue.TryTake(out trans, Timeout.Infinite))
{
// process transaction
}
// Collection is empty
}
Assume also that you have some other method that will add things to the queue. We'll call that TransactionProducer
. Your main program starts three threads: the producer and two consumers:
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();
Note that if the method that actually processes transactions uses shared resources (like a common log file), then you'll have to protect those with some kind of synchronization (a lock, perhaps).
精彩评论