我对基于事件的程序性能有疑问。 在我的公司,我们有一个交易清单。为了通过一些更改来处理它们,我们有一个计时器,它唤醒每个间隔并运行列表中的所有对象并检查数据。 我想把它改成活动基地。但我担心表现。例如,我有1000个事务与1000“日志”事件句柄将是无效的? 谢谢你的回答。 ģ
- 编辑: 假设您有一个类A的1000个对象,并且A类具有属性时间创建。 现在当时间创建大于一小时我们想要从列表中删除对象。 到目前为止,我们使用的计时器在整个列表中每15分钟运行一次,以检查创建时间是否大于一小时。但我们可以创建一个事件来做到这一点......但是注册1000并且可能是10个甚至事件处理程序对程序产生影响的时间。所以我的问题是,这是一个优秀而有效的编程吗?
答案 0 :(得分: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();
请注意,如果实际处理事务的方法使用共享资源(如公共日志文件),那么您必须保护那些具有某种同步(可能是锁定)的人。