Служба Windows и многопоточность - PullRequest
1 голос
/ 06 июня 2011

Я работаю над службой Windows, в которой я хотел бы иметь два потока. Один поток должен искать обновления (в ленте RSS) и вставлять строки в БД при обнаружении обновлений.

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

Возможно, лучшая практика - не использовать два потока. Должен ли я иметь db-соединения в обоих потоках?

Может ли кто-нибудь дать мне советы, как решить эту проблему?

1 Ответ

2 голосов
/ 06 июня 2011

Основной причиной создания многопоточного приложения или службы является выполнение базы данных или других фоновых операций без блокировки (то есть зависания) элемента представления, такого как форма Windows.Если ваш сервис зависит от очень быстрого опроса или ожидает, что вставка БД займет очень много времени, возможно, имеет смысл использовать два потока.Но я не могу себе представить, что в вашем сценарии будет так.

Если вы решите сделать свой сервис многопоточным, два основных класса в C #, на которые вы хотите посмотреть, это BackgroundWorker и ThreadPool .Если вы хотите сделать несколько одновременных вставок базы данных (например, если вы хотите выполнить вставку для каждого из нескольких RSS-каналов, опрашиваемых одновременно), вы должны использовать ThreadPool.В противном случае используйте BackgroundWorker.

Как правило, у вас есть класс доступа к базе данных, в котором есть метод для вставки строки.Этот метод создаст фонового работника, добавит обработчик DoWork к некоторому статическому методу в этом классе доступа к базе данных в фоновом работнике, а затем вызовет DoWorkAsync.У вас должны быть только настройки соединения с БД в этом одном классе, чтобы упростить поддержку кода.Например:

public static class DbAccess
{
    public void InsertRow(SomeObject entity)
    {
        BackgroundWorker bg = new BackgroundWorker();
        bg.DoWork += InsertRow_DoWork;
        bg.RunWorkerCompleted += InsertRow_RunWorkerCompleted;
        bg.RunWorkerAsync(entity);
    }

    private void InsertRow_DoWork(object sender, DoWorkEventArgs e)
    {
         BackgroundWorker bg = sender as BackgroundWorker;
         SomeObject entity = e.Argument as SomeObject;

         // insert db access here
    }

    private void InsertRow_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         // send notifications
         // alternatively, pass the InsertRow method a 
         // delegate to a method in the calling class that will notify
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...