Entity Framework 5 を使用してデータベースのキューから電子メールを読み取り、System.Net.Mail.SmtpClient を使用して SMTP サーバーに送信する Windows サービスがあります。
F# アプリケーションを作成するのは初めての試みです。私は C# のバックグラウンドを持っています。より機能的にしたり、F# の機能を十分に活用したりするには、どのように改善すればよいでしょうか? これらの変更を行う利点について説明していただけますか?
ワーカーはサービス ホストによって構築され、サービスの開始時にその作業関数が呼び出され、サービスの停止時に ContinueWorking が false に設定されます。
namespace EmailService
open log4net
open System
open System.Linq
open System.Net.Mail
open EmailService.Context
type Worker(contextFactory: EmailContextFactory, mailClient: ISmtpClient, logger: ILog) =
let MapToMessage(email : Email) =
let message = new MailMessage()
message.Sender <- new MailAddress(email.From)
message.From <- new MailAddress(email.From)
message.Subject <- email.Subject
message.Body <- email.Body
message.IsBodyHtml <- email.IsBodyHtml
message.To.Add(email.To)
(email, message)
member val ContinueWorking = true with get, set
member this.Work() =
logger.Info "Starting work"
let mutable unsentEmails = Array.empty<Email>
while this.ContinueWorking do
use context = contextFactory.GetEntities()
while this.ContinueWorking && Array.isEmpty unsentEmails do
System.Threading.Thread.Sleep(1000)
unsentEmails <- query { for q in context.QueueItems do
where (q.Error = null)
select q.Email }
|> query.Take(10)
|> query.toArray
Array.map MapToMessage unsentEmails
|> Array.iter (fun (email, message) ->
try
mailClient.SendMail(message)
email.DateSent <- new Nullable<DateTime>(DateTime.UtcNow)
context.QueueItems.Remove(email.QueueItem) |> ignore
with
| ex ->
logger.Error(ex)
email.QueueItem.Error <- ex.ToString())
context.SaveChanges() |> ignore
logger.Info (sprintf "Sent %d emails" unsentEmails.Length)
logger.Info "Work complete"