public override int GetHashCode() { unchecked { var hashCode = SubjectExpression.GetHashCode(); hashCode = (hashCode * 397) ^ FromExpression.GetHashCode(); hashCode = (hashCode * 397) ^ ForExpression.GetHashCode(); return(hashCode); } }
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); }