SmtpRetryFailedJobs Method
Puts all failed send-mail jobs back into the queue.

Namespace: MailBee.SmtpMail
Assembly: MailBee.NET (in MailBee.NET.dll) Version: 11.2.0 build 590 for .NET 4.5
public void RetryFailedJobs()

This method can be used to retry processing of all failed jobs (EXCEPT when you're using IDataReader data source, see below why). For instance, there had been some kind of network failure during processing jobs and certain e-mails failed to be sent. Then, however, the network problem was fixed. In this case, the developer can issue RetryFailedJobs to put failed jobs back into the pending queue. Then, any method which processes jobs (such as SendJobs) can be called to resume processing.

RetryFailedJobs method takes all the jobs from JobsFailed collection and puts them back to JobsPending.

Note Note
This method is thread-safe. The developer may safely call it even if some jobs are already being actively processed in the current moment. This may be useful in the case if it's needed to retry failed jobs not waiting for completion of processing the remaining jobs. For instance, if SendJobs method was still running when RetryFailedJobs was called, it will then process the newly added failed jobs as well as the remaining pending jobs.

If you want to move only specific jobs (not all failed jobs) from JobsFailed into JobsPending, use methods of SendMailJobCollection class (all job collections, including JobsFailed and JobsPending, are SendMailJobCollection instances).

This method cannot be used for mail merge job over IDataReader because in general case you can't arbitrarily access IDataReader. Once processing of IDataReader has been done, you'll usually need to recreate it. If MailBee tried to access certain rows again (to retry failed indices), it would cause database error due to forward-only nature of most data reader implementations. When using IDataReader as input, you should manually manage failed ids (see AddJob(String, String, EmailAddressCollection, IDataReader, Boolean, Boolean) for example).

This console sample performs mail merge in two runs. On the second run, all the data rows which failed to be sent out as e-mail messages on the first run are tried again. The application may complete in a single run if all the data rows have been successfully sent as e-mails within the first run.
Note Note
In the case if the application terminates after the first run and wishes to retry mail merge of failed data rows later in a separate run of the application, it needs to somehow save the list of data rows which failed on the first run (e.g. save this list in a file or database) and then pass this list to the second instance of the application (which is executed later). See GetIndicesAsString(DataTable, String) topic for details.
using System;
using System.Data;
using System.Data.OleDb;
using MailBee;
using MailBee.Mime;
using MailBee.SmtpMail;

class Sample
    // Reports successful attempt of sending e-mail.
    static void mailer_MessageSent(object sender, SmtpMessageSentEventArgs e)
        // Display e-mail address of the successful e-mail.
        Console.WriteLine(e.MergeTable.Rows[e.MergeRowIndex]["Email"] + " SUCCEEDED");

    // Reports failed attempt of sending e-mail.
    static void mailer_MessageNotSent(object sender, SmtpMessageNotSentEventArgs e)
        // Display e-mail address of the failed e-mail.
        Console.WriteLine(e.MergeTable.Rows[e.MergeRowIndex]["Email"] + " FAILED");

    static void Main(string[] args)
        Smtp mailer = new Smtp();

        // Logging into a file is useful for troubleshooting.
        mailer.Log.Filename = @"C:\Temp\log.txt";
        mailer.Log.Enabled = true;
        mailer.Log.Format = LogFormatOptions.AddContextInfo;

        // Uncomment the line below to use unlimited number of worker threads (up to 60)
        // and increase performance. Note that not all SMTP servers support this.

        // mailer.MaxThreadCount = -1;

        // Subscribe to events to track send bulk mail progress.
        mailer.MessageSent += new SmtpMessageSentEventHandler(mailer_MessageSent);
        mailer.MessageNotSent += new SmtpMessageNotSentEventHandler(mailer_MessageNotSent);

        // Setup SMTP server parameters.
        mailer.SmtpServers.Add("", "jdoe", "secret");

        // Setup e-mail message header template for mail merge.
        mailer.Message.From.AsString = "John Doe <>";
        mailer.Message.To.AsString = "##Email##";
        mailer.Message.Subject = "Our Jan/2007 newsletter";

        // Setup HTML body template.
        mailer.Message.BodyHtmlText = "<html>##Body##</html>";

        // Specify database connection string (it may be different in your case).
        string connParams = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Temp\newsletter.mdb;";

        // Make two runs of mail merge. If e-mails created from some data rows fail,
        // we'll attempt to resend them on the second run.
        for (int i = 0; i < 2; i++)
            // Initial run.
            if (i == 0)
                // Connect to the database and populate mail merge job to-do list with
                // the data from "mailing_list" table.
                using (OleDbConnection conn = new OleDbConnection(connParams))
                    // Open the connection and get the data.
                    OleDbCommand command = new OleDbCommand("SELECT * FROM mailing_list", conn);
                    OleDbDataAdapter adapter = new OleDbDataAdapter();
                    DataTable table = new DataTable();
                    adapter.SelectCommand = command;

                    // Create a job which is the following task for MailBee: perform mail merge over
                    // the specified data table and then send out each resulting e-mail to
                    // the recipients which appear in the resulting messages. ""
                    // address will be used as Return-Path (i.e. sender e-mail address).
                    mailer.AddJob(null, "", null, table);

            // Run the job. The actual mail merge takes place here.

            // Report results (row indices in the data table) to the console.
            if (mailer.JobsFailed.Count == 0)
                Console.WriteLine("All of the rows of the table have been processed and sent as e-mails.");
                if (mailer.JobsSuccessful.Count == 0)
                    Console.WriteLine("None of the rows of the table has been processed and sent as e-mail.");
                    Console.WriteLine("Not all rows of the table have been processed and sent as e-mails.");

                    Console.WriteLine("Successful rows: ");
                    Console.WriteLine(mailer.JobsSuccessful.GetIndicesAsString(null, null));

                    Console.WriteLine("Failed rows: ");
                    Console.WriteLine(mailer.JobsFailed.GetIndicesAsString(null, null));

                // Put failed data rows from mailer.JobsFailed back into the pending queue (mailer.JobsPending).

                // Clear the list of successful rows because we already displayed all successful
                // results of the first run. Next time, we want to display only those successful
                // results which had been achieved on the second run only.
See Also