private void Start_Mail_Click(object sender, RoutedEventArgs e) { if (OUBrowser.SelectedItem is DirectoryEntryContext) { var selectedOUDEContext = OUBrowser.SelectedItem as DirectoryEntryContext; if (MessageBox.Show(string.Format(CultureInfo.CurrentCulture, LabBuilder.Properties.Resources.ConfirmMailboxPopulationWindowTextFormat, selectedOUDEContext.ObjectName), LabBuilder.Properties.Resources.ConfirmationWindowTitle, MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.No) { return; } var args = new GenMailArgs(); args.selectedOUPath = selectedOUDEContext.DE.Path; args.DefaultPassword = gs.DefaultPassword; args.InitialItems = gs.InitialItems; args.Threads = gs.Threads; args.maxAdditionalRecips = gs.MaxAdditionalRecips; args.maxAttachments = gs.MaxAttachments; args.percentChanceOfAttachments = gs.PercentChanceOfAttachments; args.percentChanceOfExtraRecips = gs.PercentChanceOfExtraRecips; _bw_send.RunWorkerAsync(args); StartMailGenButton.IsEnabled = false; Settings_Button.IsEnabled = false; SendMailStatusTextBlock.Text = ""; sendMailProgress.Value = 0; sendMailProgress.Visibility = Visibility.Visible; } }
public static void Mail(GenMailArgs args, object sender, DoWorkEventArgs dwea) { ts.TraceEvent(TraceEventType.Verbose, 0, "Gen.Mail started."); // set connection limit higher ServicePointManager.DefaultConnectionLimit = 100; ts.TraceEvent(TraceEventType.Information, 0, "Initializing..."); mailUsers = MailUsers.GetAllOUMailUsers(args.selectedOUPath); ts.TraceEvent(TraceEventType.Verbose, 0, "Got list of {0} users.", mailUsers.Count); // lower maxadditionalrecips if there are not enough users if (mailUsers.Count - 1 < args.maxAdditionalRecips) { args.maxAdditionalRecips = mailUsers.Count - 1; } // load and decompress word list if necessary if (words == null) { LoadDictionary(); } ts.TraceEvent(TraceEventType.Information, 0, "Preparing recipient lists..."); var progress = new GenMailProgress(); var bw = sender as BackgroundWorker; mailCounter = 0; // clear dictionaries in case process was interrupted senderAssignments.Clear(); mailsRemainingForRecipient.Clear(); // random instance to generate seeds for other random instances var rs = new Random(); // populate mails remaining dictionary foreach (GenMailUser mu in mailUsers) { if (bw.CancellationPending == true) { dwea.Cancel = true; return; } mailsRemainingForRecipient.Add(mu.smtpAddress, args.InitialItems); } foreach (GenMailUser mu in mailUsers) { var to = new MailAddress(mu.smtpAddress, mu.displayName); while (mailsRemainingForRecipient[mu.smtpAddress] > 0) { if (bw.CancellationPending == true) { dwea.Cancel = true; return; } // keep track of # of emails to send for accurate progress later... mailCounter++; // get random user for from address GenMailUser rmu; do { rmu = mailUsers[rs.Next(mailUsers.Count)]; }while (rmu == mu && mailUsers.Count > 1); var recipList = new List <MailAddress>() { to }; // decrement mail count mailsRemainingForRecipient[mu.smtpAddress]--; // optionally add some random recipients if there are enough people in the mailusers list if (args.maxAdditionalRecips > 0 && rs.Next(1, 101) > (100 - args.percentChanceOfExtraRecips)) { // add 1 - configured max var extraRecips = rs.Next(1, args.maxAdditionalRecips + 1); // keep track of additional recips that we don't allow dupes var genMailRecips = new List <GenMailUser>(); for (int i = 0; i < extraRecips; i++) { GenMailUser recip; do { recip = mailUsers[rs.Next(mailUsers.Count)]; }while (recip == mu || genMailRecips.Contains(recip)); // don't want duplicates if (mailsRemainingForRecipient[recip.smtpAddress] > 0) { recipList.Add(new MailAddress(recip.smtpAddress, recip.displayName)); mailsRemainingForRecipient[recip.smtpAddress]--; genMailRecips.Add(recip); } } } if (senderAssignments.ContainsKey(rmu)) { senderAssignments[rmu].Add(recipList); } else { var assignments = new List <List <MailAddress> >(); assignments.Add(recipList); senderAssignments.Add(rmu, assignments); } } } // free up memory mailsRemainingForRecipient.Clear(); var tasks = senderAssignments.Count; progress.numberOfSenders = tasks; progress.numberOfMailboxes = mailUsers.Count; progress.numberOfMailsToSend = mailCounter; var actions = new Action[tasks]; int actionIndex = 0; foreach (var senderGenMailUser in senderAssignments.Keys) { if (bw.CancellationPending == true) { dwea.Cancel = true; return; } var smfua = new SendMailFromUserArgs(); smfua.backgroundWorker = bw; smfua.doWorkEventArgs = dwea; smfua.progress = progress; smfua.User = senderGenMailUser; smfua.randomInstance = new Random(rs.Next()); smfua.defaultPassword = args.DefaultPassword; smfua.percentChanceOfAttachments = args.percentChanceOfAttachments; smfua.maxAttachments = args.maxAttachments; actions[actionIndex] = () => { SendMailFromUser(smfua); }; actionIndex++; } ts.TraceEvent(TraceEventType.Information, 0, "Starting send mail threads..."); if (mailCounter < args.InitialItems * mailUsers.Count) { ts.TraceEvent(TraceEventType.Information, 0, "Since some items will be received by multiple mailboxes,\n {0:N0} items per mailbox can be achieved by sending {1:N0} item(s) total.", args.InitialItems, mailCounter); } var opts = new ParallelOptions(); //sanity check thread count if (args.Threads > 0 && args.Threads <= 100) { opts.MaxDegreeOfParallelism = args.Threads; } else { opts.MaxDegreeOfParallelism = 3; } // invoke threads. This blocks until all complte Parallel.Invoke(opts, actions); // clear sender assignments senderAssignments.Clear(); if (dwea.Cancel) { if (progress.cancelled == 2) { ts.TraceEvent(TraceEventType.Information, 0, "Mailbox population cancelled due to too many consecutive errors."); } if (progress.cancelled == 1) { ts.TraceEvent(TraceEventType.Information, 0, "Mailbox population cancelled by user."); } } else { ts.TraceEvent(TraceEventType.Information, 0, "Done sending mail."); if (mailCounter < args.InitialItems * mailUsers.Count) { ts.TraceEvent(TraceEventType.Information, 0, "Some messages were sent to multiple mailboxes.\n Sent {0:N0} item(s) total in order for each mailbox to receive {1:N0} item(s).", mailCounter, args.InitialItems); } } }