C # - очередь и многопоточность - PullRequest
1 голос
/ 30 ноября 2009

Я очень новичок в многопоточном программировании. Вот что я пытаюсь достичь:

  • Создайте службу Windows, которая непрерывно считывает базу данных (или какую-то очередь сообщений, пожалуйста, предложите, что будет лучше) для записи в таблице.
  • Ищите новую запись в таблице
  • Если есть новая запись, проверьте, достаточно ли потока в пуле потоков (не уверен, как это будет работать), запустите новый поток и сделайте некоторую работу. Во время большого трафика может быть много новых записей, поэтому мне нужно иметь многопоточность.

Спасибо всем. Пожалуйста, помогите мне с идеями и ссылкой. Я ценю вашу помощь.

Ответы [ 6 ]

2 голосов
/ 30 ноября 2009

Если возможно, вы можете рассмотреть возможность отправки базой данных сигналов о модификации. Непрерывное чтение выглядит как задом наперед. Если вы не хотите создавать свою собственную службу, вы можете использовать Windows Scheduling Services для запуска приложения для чтения базы данных. Вы не сможете использовать ThreadPool для ограничения количества одновременных действий. Но если вы создадите свой собственный сервис, использовать класс ThreadPool довольно просто. Вы можете просто установить ограничение потока и сохранить очередь рабочих элементов на основе обновлений базы данных. Также поиграйте с SetMinThreads , чтобы сохранить потоки активными и повторно используемыми.

1 голос
/ 30 ноября 2009

Я закодировал именно этот вид службы Windows, и я думаю, что вы на правильном пути. Я использую таблицу базы данных для своей очереди, которая дает мне постоянную очередь в случае сбоя системы, легко позволяет нескольким авторам по всей локальной сети и позволяет мне управлять конфликтами посредством транзакций.

Я создаю отдельные потоки для каждого процесса и отслеживаю количество активных потоков, что позволяет мне настраивать на лету. Поскольку каждый поток выполняет вызов веб-службы, использование пула потоков имело незначительную выгоду, и это также позволило мне запустить множество потоков, поскольку они блокировали ожидание на внешнем сервере.

Легко управлять, если вы разрешите только одного считывателя, что позволит вам отслеживать записи очереди, которые вы прочитали, просто используя столбец идентификации и выбирая следующий, более высокий, чем последний. По завершении потока он может удалить запись, с которой работал. Если ваш сервис выходит из строя, он просто получит первую непрочитанную запись. Вы можете стать более привлекательным, включив столбец, в котором указано, когда была произведена запись, и если обработка не удалась (возможно, из-за тайм-аута сети), вы можете отменить ее и позволить ей быть пойманным при следующем чтении. Если вам нужно иметь несколько считывателей, используйте поле отметки времени, которое указывает, когда оно было затронуто; один считыватель может восстановить другой сбойный читатель, проверив, когда запись была затронута.

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

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

Но у меня был взрыв, создающий это, и я надеюсь, что вы тоже.

1 голос
/ 30 ноября 2009

Откуда обновляется эта таблица и почему?

Если вы просто используете эту таблицу как способ «связи» между двумя приложениями, то я бы предложил использовать систему EMS, такую ​​как MSMQ. Вы можете заставить ваши 2 приложения общаться друг с другом и иметь все гарантированные качества доставки, которые идут с MSMQ. Он также встроен в WCF и довольно прост в интеграции.

Если эта таблица обновляется для какой-либо другой цели (например, вы не пытаетесь создать свою собственную систему очередей), тогда я согласен с Рашми в отношении рекомендации SqlCacheDepdency. По сути, это позволит вам подключить ваш код .NET к SQL, чтобы событие вызывалось при добавлении новой записи в таблицу или обновлении существующей (или чего-либо другого, изменяющего результирующий набор).

1 голос
/ 30 ноября 2009

Все, что вам нужно, это ThreadPool и MSMQ (простите за ссылку на статью на VB.NET); очень тривиально Технически, вы написали в своем примере опрос, а не очередь.

0 голосов
/ 30 ноября 2009

Как уже говорили другие, вам, вероятно, лучше всего использовать MSMQ. Я бы сделал еще один шаг вперед и предложил бы вам написать свой сервис с использованием WCF и развернуть его в IIS. Это не совсем просто, но Microsoft уже выполнила столько работы, которую вы хотели бы выполнить.

У Тома Холландера есть большая серия статей по настройке MSMQ, WCF и IIS здесь:

http://blogs.msdn.com/tomholl/archive/2008/07/12/msmq-wcf-and-iis-getting-them-to-play-nice-part-1.aspx

0 голосов
/ 30 ноября 2009

Если вы используете SQL Server, вы можете использовать SqlCacheDependency Class для отслеживания изменений базы данных.

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