Требуется предложение по фоновому рабочему

#c# #multithreading #wcf #backgroundworker #scheduled-tasks

#c# #многопоточность #wcf #фоновый рабочий #запланированные задачи

Вопрос:

Я хочу разработать приложение доставки (автономный сервис WCF), которое позволяет планировать отправку электронных писем. Пользователь назначит расписание электронной почте и отправит его. Служба WCF должна иметь возможность выбирать электронное письмо и отправлять его в назначенное время.

Какой подход мне использовать здесь? Я думаю о следующих альтернативах

  1. Используйте фоновый рабочий поток для выполнения этой задачи
  2. Любая сторонняя служба планирования (мне еще предстоит разобраться в этом)

Кто-нибудь может предложить мне возможное решение для этого, кроме двух вышеупомянутых?

[Редактировать] : Могу ли я использовать агенты SQL для этого?

Спасибо,

ОЗУ

Комментарии:

1. хммм, означает ли это, что я буду получать больше электронных писем с расширением? 😉

Ответ №1:

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

Если вы используете SQL Server, вы можете отправлять электронные письма непосредственно с него, а также планировать задания для отправки электронных писем, избавляя вас от необходимости развертывать службу Windows.

Комментарии:

1. Ой. Не подавайте в суд на базу данных в качестве очереди; используйте очередь. 🙂 MSMQ будет работать просто отлично, и при необходимости вы можете сохранить его на диске.

2. @Esteban Araya — почему бы и нет? В этом случае лучше использовать DB в качестве очереди, поскольку вы можете гарантировать ссылочную целостность, воспользоваться SQL и индексами.

3. @Alex Aza: Зачем очереди нужна ссылочная целостность? Зачем нужны показатели? Очередь есть очередь … и ничего больше.

4. @Esteban Araya — с практической точки зрения, это не просто очередь. У вас есть список элементов для обработки, но каждый из них должен обрабатываться по разному расписанию. После обработки элемента вы можете захотеть сохранить историю. В истории может потребоваться ссылка на расписания, электронные письма, пользователей и т.д.

Ответ №2:

Я видел «… кроме вышеупомянутых двух …», но я думаю, что нет ничего другого для достижения этого 🙂 Либо создайте бесконечный цикл внутри службы Windows следующим образом:

 private void DoTheThing()
    {
        try
        {
            while (true)
            {
                TheThing e = new TheThing();
                Thread t = new Thread(new ThreadStart(e.Run));
                t.Start();
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException) { }
        catch (Exception ex) { /* Whatever error handling you got */ }
    }
  

… где у theThing есть метод Run, который выполняет все, что вам нужно, каждые 1 секунду. Это выглядит глупо (в то время как (true) — да, верно), но работает без остановок с .NET 1.0 как минимум на 30 серверах 🙂 Просто убедитесь, что вы вызываете этот метод doTheThing при запуске вашей службы Windows в новом потоке.

Надеюсь, это поможет 🙂

Комментарии:

1. Предлагаемое вами решение хорошее, однако я ищу альтернативу, потому что фоновый поток будет выполняться в течение всего срока службы службы WCF. Меня беспокоит то, что это не должно увеличивать сложность службы WCF или bottlenexk для других процессов.

2. В принципе, цикл хорош, каждая служба представляет собой цикл под капотом. Два момента, зачем создавать новый поток каждую секунду, что, если TheThing() он замедляется? Во-вторых, и это очевидно, не полагайтесь на задержку, равную ровно одной секунде, проверьте часы, чтобы узнать, который час, не считайте итерации.

3. @Jodrell: 1. Поток. Sleep (1000) был просто примером для случаев, когда время не так важно. 2. В моих типичных проектах, где требуется фоновый цикл, задачи не зависят друг от друга, открытие каждой из них в новом потоке было бы предпочтительнее для меня именно по той причине, которую вы упомянули — если одна задача еще не завершена, а другая уже должна быть выполнена. Итак, вы абсолютно правы — запустите их в одном потоке, если они зависят друг от друга, или используйте решение, которое сохраняло бы и проверяло текущее состояние вещей.

4. @Ram: Судя по вашему сообщению и комментарию, вы рассматриваете веб-приложение в качестве хоста для своей службы WCF. Я не думаю, что веб будет работать для вас, потому что IIS перерабатывает простаивающие веб-приложения. Вы должны разместить свой WCF в службе Windows. Отредактируйте мой пример кода и комментарии.

5. Вы правы, не используйте службу, размещенную в IIS, для планирования событий, пулы приложений сбрасываются непредсказуемо, было бы лучше перейти на at (не самый лучший или даже хороший). Я просто пытался предупредить случайного читателя о потоке. Sleep (), я вижу, вы не злоупотребляли им. Наконец, если TheThing был статичным, но медленным, вы могли бы в конечном итоге столкнуться со многими потоками, использующими память, конкурирующими за ресурсы и, в конечном итоге, замораживающими службу или даже систему, несмотря на то, что код является независимым от id.

Ответ №3:

Это зависит от ваших нефункциональных требований… 🙂

Я могу представить, что вы хотели бы некоторой надежности в этом сервисе. Время жизни службы WCF зависит от ее хоста. Например. если это IIS, пул приложений будет переработан после определенного времени простоя (запросы в IIS не поступают). Это потребовало бы другого решения, чем фоновый рабочий. Как вы предполагаете, это может быть сторонний планировщик, но в Windows также есть планировщик. (см.http://technet.microsoft.com/en-us/library/dd363786 (WS.10).aspx) С помощью небольшой консольной программы вы могли бы попросить планировщик Windows вызвать вашу службу или, в качестве альтернативы, отправить само электронное письмо.

Комментарии:

1. Служба WCF не обязательно должна размещаться в IIS. В этом случае это должна быть служба Windows.

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

3. Я думал, что это было очевидно, что это не IIS. Даже если это был IIS, обрабатывающей частью должна быть служба Windows или даже запланированное консольное приложение.

4. Я полагаю, что мы согласны с тем, что вопрос не является исчерпывающим в требованиях и контексте. Все, что я могу сделать, это привести несколько примеров и указателей…