public async Task <IMailDistributorState> SendMail(DistributorData data, IMailDistributorState state) { try { var mailMessage = new MimeMessage(); mailMessage.To.Add(new MailboxAddress(data.MailInfo.ToName, data.MailInfo.ToAddress)); mailMessage.From.Add(new MailboxAddress(data.MailInfo.FromName, data.MailInfo.FromAddress)); mailMessage.Subject = data.MailInfo.Subject; var mailMessageBody = new TextPart(TextFormat.Html); mailMessageBody.Content = new MimeContent(data.DocumentResult.Stream); mailMessage.Body = mailMessageBody; try { await(state as State).SmtpClient.SendAsync(mailMessage); } catch (Exception e) { return(new SendMailStatus() { Success = false, ErrorText = e.Message }); } return(SendMailStatus.Ok()); } finally { await data.DocumentResult.Stream.DisposeAsync(); } }
public async Task <IMailDistributorState> SendMail(DistributorData data, IMailDistributorState state) { var mailMessage = new MimeMessage(); mailMessage.To.Add(new MailboxAddress(data.MailInfo.ToName, data.MailInfo.ToAddress)); mailMessage.From.Add(new MailboxAddress(data.MailInfo.FromName, data.MailInfo.FromAddress)); mailMessage.Subject = data.MailInfo.Subject; var mailMessageBody = new TextPart(TextFormat.Html); mailMessageBody.Content = new MimeContent(data.DocumentResult.Stream); mailMessage.Body = mailMessageBody; await using (var targetStream = new FileStream(Path.Combine(_workingDirectory, $"mail-to-{data.MailInfo.ToAddress}.mime"), FileMode.Create)) { await mailMessage.WriteToAsync(targetStream); } return(SendMailStatus.Ok()); }
private async Task SendSingleItem(Action <SendMailTaskProgress> progress, MailData mailData, MorestachioDocumentInfo parsedTemplate, CompiledExpression compiledAddressExpression, CompiledExpression compiledSubjectExpression, CompiledExpression compiledNameExpression, CompiledExpression compiledFromAddressExpression, CompiledExpression compiledFromNameExpression, IMailDistributorState state) { DistributorData distributorData = null; try { distributorData = await Compose(mailData, parsedTemplate, compiledAddressExpression, compiledSubjectExpression, compiledNameExpression, compiledFromAddressExpression, compiledFromNameExpression); var sendMailResult = await MailDistributor.SendMail(distributorData, state); if (!sendMailResult.Success) { progress(new SendMailTaskProgress(distributorData.MailInfo.ToAddress, sendMailResult.ErrorText)); } else { progress(new SendMailTaskProgress(distributorData.MailInfo.ToAddress)); } } catch (Exception e) { progress(new SendMailTaskProgress(distributorData?.MailInfo.ToAddress, e.Message)); } }
public async Task <ComposeMailResult> ComposeAndSend(IProgress <SendMailProgress> progress, CancellationToken stopRequestedToken) { var compiledAddressExpression = ToAddressExpression.Compile(); var compiledNameExpression = ToNameExpression.Compile(); var compiledSubjectExpression = SubjectExpression.Compile(); var compiledFromAddressExpression = FromAddressExpression.Compile(); var compiledFromNameExpression = FromNameExpression.Compile(); var parsingOptions = new ParserOptions(Template); parsingOptions.Timeout = TimeSpan.FromMinutes(1); parsingOptions.Formatters.AddFromType(typeof(LinqFormatter)); parsingOptions.Formatters.AddFromType(typeof(DynamicLinq)); var parsedTemplate = await Parser.ParseWithOptionsAsync(parsingOptions); var sendData = 0; var sendSuccess = 0; var buffered = 0; var currentlyProcessing = 0; var sendFailed = new ConcurrentDictionary <MailData, SendMailStatus>(); var maxSendData = await MailDataStrategy.Count(); var mailDatas = await MailDataStrategy.GetMails(); #if DEBUG var rand = new Random(1337); #endif void Progress(SendMailTaskProgress taskProgress, MailData mailData) { Interlocked.Add(ref sendData, 1); if (!taskProgress.Success) { sendFailed.TryAdd(mailData, new SendMailStatus() { ErrorText = taskProgress.Error }); } else { Interlocked.Add(ref sendSuccess, 1); } progress.Report(new SendMailProgress(taskProgress.To, sendData, maxSendData, true, sendSuccess, sendFailed.Count, buffered, currentlyProcessing)); } if (SendInParallel) { var consumerItems = new BlockingCollection <MailData>(new ConcurrentBag <MailData>()); IMailDistributorState globalState = null; if (MailDistributor.ParallelSupport == ParallelSupport.Full) { globalState = await MailDistributor.BeginSendMail(); } var threads = new Thread[ParallelNoOfParallism]; for (int i = 0; i < threads.Length; i++) { void Start() { try { IMailDistributorState threadState = globalState; if (MailDistributor.ParallelSupport == ParallelSupport.MultiInstance) { threadState = MailDistributor.BeginSendMail().ConfigureAwait(true).GetAwaiter() .GetResult(); } foreach (var mailData in consumerItems.GetConsumingEnumerable()) { Interlocked.Add(ref currentlyProcessing, 1); Interlocked.Exchange(ref buffered, consumerItems.Count); if (stopRequestedToken.IsCancellationRequested) { break; } //#if DEBUG // Task.Delay(rand.Next(1050, 2000), stopRequestedToken) // .ConfigureAwait(true).GetAwaiter().GetResult(); //#endif SendSingleItem(taskProgress => { #if DEBUG if (rand.Next(0, 2) == 1) { taskProgress = new SendMailTaskProgress(taskProgress.To, "RAND"); } #endif Progress(taskProgress, mailData); }, mailData, parsedTemplate, compiledAddressExpression, compiledSubjectExpression, compiledNameExpression, compiledFromAddressExpression, compiledFromNameExpression, threadState).ConfigureAwait(true).GetAwaiter().GetResult(); Interlocked.Add(ref currentlyProcessing, -1); } if (MailDistributor.ParallelSupport == ParallelSupport.MultiInstance) { threadState = MailDistributor.EndSendMail(threadState).ConfigureAwait(true).GetAwaiter() .GetResult(); } } catch (Exception e) { } finally { } } var thread = new Thread(Start); thread.IsBackground = true; thread.Name = "MailComposerConsumer_" + i; thread.Priority = ThreadPriority.Normal; thread.TrySetApartmentState(ApartmentState.MTA); threads[i] = thread; } foreach (var thread in threads) { thread.Start(); } var readAheadCount = ParallelReadAheadCount; await foreach (var item in mailDatas.WithCancellation(stopRequestedToken)) { consumerItems.Add(item, stopRequestedToken); while (consumerItems.Count >= readAheadCount) { await Task.Delay(10, stopRequestedToken); } } consumerItems.CompleteAdding(); try { foreach (var thread in threads) { thread.Join(); } } catch (Exception e) { } if (MailDistributor.ParallelSupport == ParallelSupport.Full) { globalState = await MailDistributor.EndSendMail(globalState); } } else { var beginSend = await MailDistributor.BeginSendMail(); Interlocked.Add(ref currentlyProcessing, 1); await foreach (var mailData in mailDatas.WithCancellation(stopRequestedToken)) { buffered = 1; if (stopRequestedToken.IsCancellationRequested) { break; } //#if DEBUG // await Task.Delay(rand.Next(150, 200), stopRequestedToken); //#endif await SendSingleItem(taskProgress => { #if DEBUG if (rand.Next(0, 2) == 1) { taskProgress = new SendMailTaskProgress(taskProgress.To, "RAND"); } #endif Progress(taskProgress, mailData); }, mailData, parsedTemplate, compiledAddressExpression, compiledSubjectExpression, compiledNameExpression, compiledFromAddressExpression, compiledFromNameExpression, beginSend); } buffered = 0; Interlocked.Add(ref currentlyProcessing, -1); await MailDistributor.EndSendMail(beginSend); } var resultData = new ComposeMailResult(); resultData.SendSuccessfully = sendData; resultData.SendFailed = sendFailed.ToDictionary(e => e.Key, e => e.Value); progress.Report(new SendMailProgress("", sendData, maxSendData, true, sendSuccess, sendFailed.Count, buffered, currentlyProcessing)); return(resultData); }
public async Task <IMailDistributorState> EndSendMail(IMailDistributorState state) { await Task.CompletedTask; return(SendMailStatus.Ok()); }
public async Task <IMailDistributorState> EndSendMail(IMailDistributorState state) { await(state as State).SmtpClient.DisconnectAsync(true); (state as State).SmtpClient.Dispose(); return(SendMailStatus.Ok()); }