программа на основе событий - PullRequest
0 голосов
/ 21 января 2011

У меня вопрос по поводу производительности программы на основе событий. в моей компании у нас есть список транзакций. чтобы справиться с ними некоторыми изменениями, у нас есть таймер, который просыпается каждый интервал и запускается на всех объектах в списке и проверяет данные. я хочу изменить его на базы событий. но я беспокоюсь о производительности. например, у меня есть 1000 транзакций с 1000 "log" для обработчиков событий, это будет неэффективно? спасибо за любой ответ. G

- редактирование: Допустим, у вас есть 1000 объектов класса А. и класс А имеют свойство время создания. теперь, когда время создания больше часа, мы хотим стереть объект из списка. до сих пор мы использовали таймер, который запускался каждые 15 минут во всем списке, чтобы проверить, что время создания больше часа. но мы можем создать событие, чтобы сделать это ... но зарегистрировать 1000 и может быть десять раз, даже обработчики событий могут повлиять на программы. так что мой вопрос: это хорошее и эффективное программирование?

1 Ответ

2 голосов
/ 21 января 2011

Вместо архитектуры, основанной на событиях, вы можете рассмотреть возможность использования модели производитель / потребитель, аналогичной той, которая у вас уже есть. Но вместо пробуждения через интервал используйте 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 - это незанятое ожидание, поэтому он не будет потреблять циклы процессора.

Это должно быть намного проще реализовать, чем система, основанная на событиях, и обеспечить лучшую производительность. Вам также не нужно беспокоиться о слишком большом количестве одновременных событий, вызывающих проблему. Очередь будет буферизовать вещи, чтобы вы могли обрабатывать транзакции как можно быстрее. Это также позволит вам создать несколько потребителей, если вам нужно / нужно.

Пример, по запросу:

Например, возьмите приведенный выше код и поместите его в поток 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();

Обратите внимание, что если метод, который на самом деле обрабатывает транзакции, использует общие ресурсы (например, общий файл журнала), вам придется защищать их с помощью некоторой синхронизации (возможно, блокировки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...