Bounce Inspector Features

Handle bounced messages

Ultimate Bounce Inspector makes it easy for you to process EML and Outlook MSG bounce messages. It also supports processing messages on IMAP and POP3 mailboxes on-the-fly.

High-performance and reliable Bounce Inspector

When it comes to performance and reliability, Ultimate Bounce Inspector component for .NET, outperforms all similar components on the market. In our performance test, BounceInspector takes only 10 to 20 milliseconds on average (Console Application running on a 2.4GHz PC with 1GB RAM) to scan a bounced e-mail message. In addition, the bounce signature database is regularly updated and you can get the updates by simply downloading and installing our new versions.

If you encounter any unrecognized bounced email messages, please do not hesistate to send us your bounced email messages to support@componentpro.com or use our Feedback form to send your concerns to us. We will provide you a hot-fix containing new bounce signatures that recognize the bounced email messages you sent us within 1 business day.

Supports both EML and Outlook MSG file formats

When designing the Bounce Inspector component, we mainly forcus on ease-of-use, performance, reliability, and flexibility. As a benefit, you only need a single line of code to scan thousands of bounced EML messages on local disk and get the accurate inspection result. You can either specify the path to the directory containing EML files or a list of EML file names to scan. BounceInspector will do all the hard works for you.

The Ultimate Bounce Inspector also supports MIME and S/MIME, providing your applications the ability to encrypt, decrypt, sign, and validate email messages.

Process a single EML or Outlook MSG file

Using the Process method, you can quickly analyze a message and retrieve the result containing useful information such as Bounced Address, Bounce Category, Bounce Type, Delivery Status Notification(DSN) information, etc. Below is the code used to analyze a single EML file:

// Create a new instance of the BounceInspector class.
BounceInspector inspector = new BounceInspector();
// Process an EML file.
BounceResult r = inspector.Process("c:\\temp\\my eml.eml");

// To process an Outlook MSG file, you can use the same code.
// BounceResult r = inspector.Process("c:\\temp\\my outlook message.msg");

// If this message was identified as a bounced email message.
if (r.Identified)
    Console.WriteLine("To E-mail: {0}\r\nFrom E-mail: {1}\r\nBounced E-mail: {2}\r\nBounce Category: {3}\r\nBounce Type {4}",
    r.MailMessage.To[0].Address, r.MailMessage.From[0].Address, r.Addresses, r.BounceCategory, r.BounceType);
else
    Console.WriteLine("No bounce information found");
' Create a new instance of the BounceInspector class.
Dim inspector As New BounceInspector()
' Process an EML file.
Dim r As BounceResult = inspector.Process("c:\temp\my eml.eml")

' To process an Outlook MSG file, you can use the same code.
' BounceResult r = inspector.Process("c:\\temp\\my outlook message.msg");

' If this message was identified as a bounced email message.
If r.Identified Then
    Console.WriteLine("To E-mail: {0}" & vbCrLf & "From E-mail: {1}" & vbCrLf & "Bounced E-mail: {2}" & vbCrLf & "Bounce Category: {3}" & vbCrLf & "Bounce Type {4}", r.MailMessage.To(0).Address, r.MailMessage.From(0).Address, r.Addresses, r.BounceCategory, r.BounceType)
Else
    Console.WriteLine("No bounce information found")
End If
// Create a new instance of the BounceInspector class.
BounceInspector inspector = new BounceInspector();

// Process all EML files in directory 'c:\\temp'.
BounceResultCollection result = inspector.ProcessMessages("c:\\temp");

// Display processed emails.
foreach (BounceResult r in result)
{
    // If this message was identified as a bounced email message.
    if (r.Identified)
    {
        // Print out the result
        Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\n" + 
                      "Bounce Category: {3}\n" + 
                      "Bounce Type: {4}\nDeleted: {5}\n" + 
                      "DSN Action: {6}\n" + 
                      "DSN Diagnostic Code: {7}\n\n",
                        System.IO.Path.GetFileName(r.FilePath),
                        r.MailMessage.Subject,
                        r.Addresses[0],
                        r.BounceCategory.Name,
                        r.BounceType.Name,
                        r.FileDeleted,
                        r.Dsn.Action,
                        r.Dsn.DiagnosticCode);
    }
}

Console.WriteLine("{0} bounced message found", result.BounceCount);
' Create a new instance of the BounceInspector class.
Dim inspector As New BounceInspector()

' Process all EML files in directory 'c:\\temp'.
Dim result As BounceResultCollection = inspector.ProcessMessages("c:\temp")

' Display processed emails.
For Each r As BounceResult In result
    ' If this message was identified as a bounced email message.
    If r.Identified Then
        ' Print out the result
        Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
    End If
Next r

Console.WriteLine("{0} bounced message found", result.BounceCount)

Process multiple mail message files

Multiple EML files can be processed with a single line of code. The following example shows how to use ProcessMessages method to achieve that.

Download and processing multiple EML files from a IMAP server

You can download and process messages from either IMAP server or IMAP server. To download and process messages from a IMAP server, you can use the following code:

static void Main()
{            
    try
    {
        // IMAP server information.
        const string serverName = "myserver";
        const string user = "name@domain.com";
        const string password = "mytestpassword";
        const int port = 993;
        const SslSecurityMode securityMode = SslSecurityMode.Implicit;

        // Create a new instance of the Imap class.
        Imap client = new Imap();
        
        Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port);
        // Connect to the server.
        client.Connect(serverName, port, securityMode);

        // Login to the server.
        Console.WriteLine("Logging in as {0}...", user);
        client.Authenticate(user, password);

        // Initialize BounceInspector.
        BounceInspector inspector = new BounceInspector();
        inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.

        // Register processed event handler.
        inspector.Processed += inspector_Processed;

        // Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
        BounceResultCollection result = inspector.ProcessMessages(client, "Inbox", "c:\\test");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);

        // Disconnect.
        Console.WriteLine("Disconnecting...");
        client.Disconnect();

    }
    catch (ImapException imapExc)
    {
        Console.WriteLine(string.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status));
    }
    catch (Exception exc)
    {
        Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Processed event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject);
}
Try
    ' IMAP server information.
    Const serverName As String = "myserver"
    Const user As String = "name@domain.com"
    Const password As String = "mytestpassword"
    Const port As Integer = 993
    Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

    ' Create a new instance of the Imap class.
    Dim client As New Imap()

    Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    ' Initialize BounceInspector.
    Dim inspector As New BounceInspector()
    inspector.AllowInboxDelete = False ' true if you want BounceInspector automatically delete all hard bounces.

    ' Register processed event handler.
    AddHandler inspector.Processed, AddressOf inspector_Processed

    ' Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
    Dim result As BounceResultCollection = inspector.ProcessMessages(client, "Inbox", "c:\test")

    ' Display processed emails.
    For Each r As BounceResult In result
        ' If this message was identified as a bounced email message.
        If r.Identified Then
            ' Print out the result
            Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
        End If
    Next r

    Console.WriteLine("{0} bounced message found", result.BounceCount)

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()

Catch imapExc As ImapException
    Console.WriteLine(String.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status))
Catch exc As Exception
    Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
End Try
Sub

<summary>
Handles the BounceInspector's Processed event.
</summary>
<param name="sender">The BounceInspector object.</param>
<param name="e">The event arguments.</param>
ate Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject)
Sub
static void Main()
{            
    try
    {
        // IMAP server information.
        const string serverName = "myserver";
        const string user = "name@domain.com";
        const string password = "mytestpassword";
        const int port = 993;
        const SslSecurityMode securityMode = SslSecurityMode.Implicit;

        // Create a new instance of the Imap class.
        Imap client = new Imap();
        
        Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port);
        // Connect to the server.
        client.Connect(serverName, port, securityMode);

        // Login to the server.
        Console.WriteLine("Logging in as {0}...", user);
        client.Authenticate(user, password);

        // Initialize BounceInspector.
        BounceInspector inspector = new BounceInspector();
        inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.

        // Register processed event handler.
        inspector.Processed += inspector_Processed;

        // Get the list of unread messages.
        ImapMessageCollection list = client.ListMessages(ImapEnvelopeParts.MessageInboxIndex | ImapEnvelopeParts.Size, ImapCriterion.DontHaveFlags(ImapMessageFlags.Seen));

        // Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
        BounceResultCollection result = inspector.ProcessMessages(client, "Inbox", list, "c:\\test");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);

        // Disconnect.
        Console.WriteLine("Disconnecting...");
        client.Disconnect();

    }
    catch (ImapException imapExc)
    {
        Console.WriteLine(string.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status));
    }
    catch (Exception exc)
    {
        Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Processed event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject);
}
Try
    ' IMAP server information.
    Const serverName As String = "myserver"
    Const user As String = "name@domain.com"
    Const password As String = "mytestpassword"
    Const port As Integer = 993
    Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

    ' Create a new instance of the Imap class.
    Dim client As New Imap()

    Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    ' Initialize BounceInspector.
    Dim inspector As New BounceInspector()
    inspector.AllowInboxDelete = False ' true if you want BounceInspector automatically delete all hard bounces.

    ' Register processed event handler.
    AddHandler inspector.Processed, AddressOf inspector_Processed

    ' Get the list of unread messages.
    Dim list As ImapMessageCollection = client.ListMessages(ImapEnvelopeParts.MessageInboxIndex Or ImapEnvelopeParts.Size, ImapCriterion.DontHaveFlags(ImapMessageFlags.Seen))

    ' Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
    Dim result As BounceResultCollection = inspector.ProcessMessages(client, "Inbox", list, "c:\test")

    ' Display processed emails.
    For Each r As BounceResult In result
        ' If this message was identified as a bounced email message.
        If r.Identified Then
            ' Print out the result
            Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
        End If
    Next r

    Console.WriteLine("{0} bounced message found", result.BounceCount)

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()

Catch imapExc As ImapException
    Console.WriteLine(String.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status))
Catch exc As Exception
    Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
End Try
Sub

<summary>
Handles the BounceInspector's Processed event.
</summary>
<param name="sender">The BounceInspector object.</param>
<param name="e">The event arguments.</param>
ate Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject)
Sub

Download and process unread message from IMAP server

To download and process unread messages, you will need to call the ListMessages with ImapCriterion.DontHaveFlags(ImapMessageFlags.Seen). The following code takes advantage of the method to download and process all unread messages from an IMAP account:

Download and process multiple message from POP3 server

You can download and process messages from either IMAP server or POP3 server. To download and process messages from a POP3 server, you can use the following code:

static void Main()
{
    try
    {
        // POP3 server information.
        const string serverName = "myserver";
        const string user = "name@domain.com";
        const string password = "mytestpassword";
        const int port = 995;
        const SslSecurityMode securityMode = SslSecurityMode.Implicit;

        // Create a new instance of the Pop3 class.
        Pop3 client = new Pop3();
        
        Console.WriteLine("Connecting Pop3 server: {0}:{1}...", serverName, port);
        // Connect to the server.
        client.Connect(serverName, port, securityMode);

        // Login to the server.
        Console.WriteLine("Logging in as {0}...", user);
        client.Authenticate(user, password);

        // Initialize BounceInspector.
        BounceInspector inspector = new BounceInspector();
        inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.

        // Register processed event handler.
        inspector.Processed += inspector_Processed;

        // Download messages from Pop3 Inbox to 'c:\test' and process them.
        BounceResultCollection result = inspector.ProcessMessages(client, "c:\\test");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);

        // Disconnect.
        Console.WriteLine("Disconnecting...");
        client.Disconnect();

    }
    catch (Pop3Exception Pop3Exc)
    {
        Console.WriteLine(string.Format("An Pop3 error occurred: {0}, ErrorStatus: {1}", Pop3Exc.Message, Pop3Exc.Status));
    }
    catch (Exception exc)
    {
        Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Processed event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject);
}
Try
    ' POP3 server information.
    Const serverName As String = "myserver"
    Const user As String = "name@domain.com"
    Const password As String = "mytestpassword"
    Const port As Integer = 995
    Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

    ' Create a new instance of the Pop3 class.
    Dim client As New Pop3()

    Console.WriteLine("Connecting Pop3 server: {0}:{1}...", serverName, port)
    ' Connect to the server.
    client.Connect(serverName, port, securityMode)

    ' Login to the server.
    Console.WriteLine("Logging in as {0}...", user)
    client.Authenticate(user, password)

    ' Initialize BounceInspector.
    Dim inspector As New BounceInspector()
    inspector.AllowInboxDelete = False ' true if you want BounceInspector automatically delete all hard bounces.

    ' Register processed event handler.
    AddHandler inspector.Processed, AddressOf inspector_Processed

    ' Download messages from Pop3 Inbox to 'c:\test' and process them.
    Dim result As BounceResultCollection = inspector.ProcessMessages(client, "c:\test")

    ' Display processed emails.
    For Each r As BounceResult In result
        ' If this message was identified as a bounced email message.
        If r.Identified Then
            ' Print out the result
            Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
        End If
    Next r

    Console.WriteLine("{0} bounced message found", result.BounceCount)

    ' Disconnect.
    Console.WriteLine("Disconnecting...")
    client.Disconnect()

Catch Pop3Exc As Pop3Exception
    Console.WriteLine(String.Format("An Pop3 error occurred: {0}, ErrorStatus: {1}", Pop3Exc.Message, Pop3Exc.Status))
Catch exc As Exception
    Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
End Try
Sub

<summary>
Handles the BounceInspector's Processed event.
</summary>
<param name="sender">The BounceInspector object.</param>
<param name="e">The event arguments.</param>
ate Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
Console.WriteLine("Processing mail with subject '{0}'...", e.MailMessage.Subject)
Sub

Events

You can handle the events in the Pop3 class to get notified when an event is triggered.

DownloadingMessage event

DownloadingMessage event is triggered when a message is being downloaded from a POP3 or IMAP server. By handling this event, you can tell BounceInspector to skip downloading the message or to change the destination EML file name.

We will take advantages of this event with the following code examples:

static void Main()
{
    // IMAP server information.
    const string serverName = "myserver";
    const string user = "name@domain.com";
    const string password = "mytestpassword";
    const int port = 993;
    const SslSecurityMode securityMode = SslSecurityMode.Implicit;

    // Create a new instance of the Imap class.
    Imap client = new Imap();
    try
    {
        Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port);
        // Connect to the server.
        client.Connect(serverName, port, securityMode);

        // Login to the server.
        Console.WriteLine("Logging in as {0}...", user);
        client.Authenticate(user, password);

        // Initialize BounceInspector.
        BounceInspector inspector = new BounceInspector();
        inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.

        // Handle events.
        inspector.Processing += inspector_Processing;
        inspector.Processed += inspector_Processed;
        inspector.DownloadingMessage += inspector_DownloadingMessage;

        // Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
        BounceResultCollection result = inspector.ProcessMessages(client, "Inbox", "c:\\test");
        // Download messages from IMAP 'Inbox' folder to memory stream and process them.
        //BounceResultCollection result = inspector.ProcessMessages(client, "Inbox");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);

        // Disconnect.
        Console.WriteLine("Disconnecting...");
        client.Disconnect();

    }
    catch (ImapException imapExc)
    {
        MessageBox.Show(string.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status));
    }
    catch (Exception exc)
    {
        MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
    }
}

static void inspector_Processing(object sender, ProcessingEventArgs e)
{
    // Skip all messages containing "Test" in subject.
    if (e.MailMessage.Subject.IndexOf("Test") != -1)
        e.Skip = true;
}

static int id = 0;            

/// <summary>
/// Handles the BounceInspector's DownloadingMessages event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_DownloadingMessage(object sender, DownloadingMessageEventArgs e)
{
    if (e.FileExists)
        // Skip if message containing "Cxj89" already exists.
        if (e.ImapMessage.UniqueId.IndexOf("Cxj89") != -1)
        {
            e.Skip = true;
        }
        // Otherwise rename destination file name.
        else
        {
            e.FileName = "tmp" + id;
            id++;
            // You can also set e.DirectoryName to another destination folder.
            // e.DirectoryName = "temp";
        }
}

/// <summary>
/// Handles the BounceInspector's Processed event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    Console.WriteLine("Processed mail with subject '{0}'...", e.MailMessage.Subject);
}
Shared Sub Main()
    ' IMAP server information.
    Const serverName As String = "myserver"
    Const user As String = "name@domain.com"
    Const password As String = "mytestpassword"
    Const port As Integer = 993
    Const securityMode As SslSecurityMode = SslSecurityMode.Implicit

    ' Create a new instance of the Imap class.
    Dim client As New Imap()
    Try
        Console.WriteLine("Connecting IMAP server: {0}:{1}...", serverName, port)
        ' Connect to the server.
        client.Connect(serverName, port, securityMode)

        ' Login to the server.
        Console.WriteLine("Logging in as {0}...", user)
        client.Authenticate(user, password)

        ' Initialize BounceInspector.
        Dim inspector As New BounceInspector()
        inspector.AllowInboxDelete = False ' true if you want BounceInspector automatically delete all hard bounces.

        ' Handle events.
        AddHandler inspector.Processing, AddressOf inspector_Processing
        AddHandler inspector.Processed, AddressOf inspector_Processed
        AddHandler inspector.DownloadingMessage, AddressOf inspector_DownloadingMessage

        ' Download messages from IMAP 'Inbox' folder to 'c:\test' and process them.
        Dim result As BounceResultCollection = inspector.ProcessMessages(client, "Inbox", "c:\test")
        ' Download messages from IMAP 'Inbox' folder to memory stream and process them.
        'BounceResultCollection result = inspector.ProcessMessages(client, "Inbox");

        ' Display processed emails.
        For Each r As BounceResult In result
            ' If this message was identified as a bounced email message.
            If r.Identified Then
                ' Print out the result
                Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
            End If
        Next r

        Console.WriteLine("{0} bounced message found", result.BounceCount)

        ' Disconnect.
        Console.WriteLine("Disconnecting...")
        client.Disconnect()

    Catch imapExc As ImapException
        MessageBox.Show(String.Format("An IMAP error occurred: {0}, ErrorStatus: {1}", imapExc.Message, imapExc.Status))
    Catch exc As Exception
        MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
    End Try
End Sub

Private Shared Sub inspector_Processing(ByVal sender As Object, ByVal e As ProcessingEventArgs)
    ' Skip all messages containing "Test" in subject.
    If e.MailMessage.Subject.IndexOf("Test") <> -1 Then
        e.Skip = True
    End If
End Sub

Private Shared id As Integer = 0

''' <summary>
''' Handles the BounceInspector's DownloadingMessages event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_DownloadingMessage(ByVal sender As Object, ByVal e As DownloadingMessageEventArgs)
    If e.FileExists Then
        ' Skip if message containing "Cxj89" already exists.
        If e.ImapMessage.UniqueId.IndexOf("Cxj89") <> -1 Then
            e.Skip = True
        ' Otherwise rename destination file name.
        Else
            e.FileName = "tmp" & id
            id += 1
            ' You can also set e.DirectoryName to another destination folder.
            ' e.DirectoryName = "temp";
        End If
    End If
End Sub

''' <summary>
''' Handles the BounceInspector's Processed event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
    Console.WriteLine("Processed mail with subject '{0}'...", e.MailMessage.Subject)
End Sub
static void Main()
{
    try
    {
        // Create a new instance of the BounceInspector class.
        BounceInspector inspector = new BounceInspector();

        // Register the event handler to the Processed event.
        inspector.Processed += inspector_Processed;
        
        // and Processing event.
        inspector.Processing += inspector_Processing;

        // Register the event handler to the Progress event.
        inspector.Progress += inspector_Progress;

        // Process all EML files in directory 'c:\\temp'.
        BounceResultCollection result = inspector.ProcessMessages("c:\\temp");                

        Console.WriteLine("{0} bounced message found", result.BounceCount);
    }
    catch (Exception exc)
    {
        MessageBox.Show(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Processing event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processing(object sender, ProcessingEventArgs e)
{
    Console.WriteLine("Processing message {0}", e.Filename);
    // Skip some files.
    if (e.Filename.IndexOf("test.eml") != -1)
        e.Skip = true;
}

/// <summary>
/// Handles the BounceInspector's Processed event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    BounceResult r = e.Result;

    // If this message was identified as a bounced email message and the message object is not null.
    if (r.Identified && r.MailMessage != null)
    {
        // Print out the result
        Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                        System.IO.Path.GetFileName(r.FilePath),
                        r.MailMessage.Subject,
                        r.Addresses[0],
                        r.BounceCategory.Name,
                        r.BounceType.Name,
                        r.FileDeleted,
                        r.Dsn.Action,
                        r.Dsn.DiagnosticCode);
    }
}

/// <summary>
/// Handles the BounceInspector's Progress event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Progress(object sender, ProgressEventArgs e)
{
    Console.WriteLine("{0}/{1} message(s) processed", e.Current, e.Total);
}
Shared Sub Main()
    Try
        ' Create a new instance of the BounceInspector class.
        Dim inspector As New BounceInspector()

        ' Register the event handler to the Processed event.
        AddHandler inspector.Processed, AddressOf inspector_Processed

        ' and Processing event.
        AddHandler inspector.Processing, AddressOf inspector_Processing

        ' Register the event handler to the Progress event.
        AddHandler inspector.Progress, AddressOf inspector_Progress

        ' Process all EML files in directory 'c:\\temp'.
        Dim result As BounceResultCollection = inspector.ProcessMessages("c:\temp")

        Console.WriteLine("{0} bounced message found", result.BounceCount)
    Catch exc As Exception
        MessageBox.Show(String.Format("An error occurred: {0}", exc.Message))
    End Try
End Sub

''' <summary>
''' Handles the BounceInspector's Processing event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Processing(ByVal sender As Object, ByVal e As ProcessingEventArgs)
    Console.WriteLine("Processing message {0}", e.Filename)
    ' Skip some files.
    If e.Filename.IndexOf("test.eml") <> -1 Then
        e.Skip = True
    End If
End Sub

''' <summary>
''' Handles the BounceInspector's Processed event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
    Dim r As BounceResult = e.Result

    ' If this message was identified as a bounced email message and the message object is not null.
    If r.Identified AndAlso r.MailMessage IsNot Nothing Then
        ' Print out the result
        Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
    End If
End Sub

''' <summary>
''' Handles the BounceInspector's Progress event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs)
    Console.WriteLine("{0}/{1} message(s) processed", e.Current, e.Total)
End Sub

Processing and Processed events event

Processing event is triggered when a message is being processed. By handling this event, you can show information about the message and ask user or programmatically skip or allow processing the message. Processed event is fired when the message has been processed and the result can be obtained via the event handler's argument.

Progress event

Progress event is triggered when a block of data has been sent or received. By handling this event, you can display transfer progress information, source file name, destination file name, etc.

static void Main()
{
    try
    {
        // Create a new instance of the BounceInspector class.
        BounceInspector inspector = new BounceInspector();

        // Register an event handler.
        inspector.Progress += inspector_Progress;

        // Process all EML files in directory 'c:\\temp'.
        BounceResultCollection result = inspector.ProcessMessages("c:\\temp");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);
    }
    catch (Exception exc)
    {
        Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Progress event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Progress(object sender, ProgressEventArgs e)
{
    Console.WriteLine("{0}/{1} message(s) processed, {2}% completed", e.Current, e.Total, e.Percentage);
}
Shared Sub Main()
    Try
        ' Create a new instance of the BounceInspector class.
        Dim inspector As New BounceInspector()

        ' Register an event handler.
        AddHandler inspector.Progress, AddressOf inspector_Progress

        ' Process all EML files in directory 'c:\\temp'.
        Dim result As BounceResultCollection = inspector.ProcessMessages("c:\temp")

        ' Display processed emails.
        For Each r As BounceResult In result
            ' If this message was identified as a bounced email message.
            If r.Identified Then
                ' Print out the result
                Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
            End If
        Next r

        Console.WriteLine("{0} bounced message found", result.BounceCount)
    Catch exc As Exception
        Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
    End Try
End Sub

''' <summary>
''' Handles the BounceInspector's Progress event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs)
    Console.WriteLine("{0}/{1} message(s) processed, {2}% completed", e.Current, e.Total, e.Percentage)
End Sub

Advanced Features

The library also comes with some advanced features below:

Access original message

Some DSN (Delivery Status Notification) messages embed the original messages as files. To access the original message, you will need to load it from the attachment and after that you can manipulate the loaded message normally. The following example shows you how to use the MailMessage class to access the original message:

// Create a new instance of the BounceInspector class.
BounceInspector inspector = new BounceInspector();
// Process an EML file (you should change the file name here).
BounceResult r = inspector.Process("C:\\ComponentPro\\NetProducts\\Branches\\2009v4\\UltimateBounceInspector\\UnitTest\\Data\\FB043DC5B1CC4DD092056CEE1E47AEC9.eml");

// If this message was identified as a bounced email message.
if (r.Identified)
{
    Console.WriteLine("To E-mail: {0}\r\nFrom E-mail: {1}\r\nBounced E-mail: {2}\r\nBounce Category: {3}\r\nBounce Type {4}",
    r.MailMessage.To[0].Address, r.MailMessage.From[0].Address, r.Addresses, r.BounceCategory, r.BounceType);

    // If it contains attachments.
    if (r.MailMessage.Attachments.Count > 0)
    {
        foreach (Attachment at in r.MailMessage.Attachments)
        {
            // Try to find the orginal message.
            if (at.FileName.EndsWith(".eml", StringComparison.InvariantCultureIgnoreCase))
            {
                // Create a new MailMessage object from the attachment.
                MailMessage msg = new MailMessage(at.GetContentStream());
                // Print out all name value pairs in the message headers.
                foreach (Header header in msg.Headers)
                {
                    Console.WriteLine("Header Name: {0}, Value: {1}", header.Name, header.Raw);
                    // Do something here.
                    // ...
                }
            }
        }
    }
}
else
    Console.WriteLine("No bounce information found");
' Create a new instance of the BounceInspector class.
Dim inspector As New BounceInspector()
' Process an EML file (you should change the file name here).
Dim r As BounceResult = inspector.Process("C:\ComponentPro\NetProducts\Branches\2009v4\UltimateBounceInspector\UnitTest\Data\FB043DC5B1CC4DD092056CEE1E47AEC9.eml")

' If this message was identified as a bounced email message.
If r.Identified Then
    Console.WriteLine("To E-mail: {0}" & vbCrLf & "From E-mail: {1}" & vbCrLf & "Bounced E-mail: {2}" & vbCrLf & "Bounce Category: {3}" & vbCrLf & "Bounce Type {4}", r.MailMessage.To(0).Address, r.MailMessage.From(0).Address, r.Addresses, r.BounceCategory, r.BounceType)

    ' If it contains attachments.
    If r.MailMessage.Attachments.Count > 0 Then
        For Each at As Attachment In r.MailMessage.Attachments
            ' Try to find the orginal message.
            If at.FileName.EndsWith(".eml", StringComparison.InvariantCultureIgnoreCase) Then
                ' Create a new MailMessage object from the attachment.
                Dim msg As New MailMessage(at.GetContentStream())
                ' Print out all name value pairs in the message headers.
                For Each header As Header In msg.Headers
                    Console.WriteLine("Header Name: {0}, Value: {1}", header.Name, header.Raw)
                    ' Do something here.
                    ' ...
                Next header
            End If
        Next at
    End If
Else
    Console.WriteLine("No bounce information found")
End If
// Create a new instance of the BounceInspector class.
BounceInspector inspector = new BounceInspector();
// Process an EML file (you should change the file name here).
BounceResult r = inspector.Process("C:\\ComponentPro\\NetProducts\\Branches\\2009v4\\UltimateBounceInspector\\UnitTest\\Data\\FB043DC5B1CC4DD092056CEE1E47AEC9.eml");

// If this message was identified as a bounced email message.
if (r.Identified)
{
    Console.WriteLine("To E-mail: {0}\r\nFrom E-mail: {1}\r\nBounced E-mail: {2}\r\nBounce Category: {3}\r\nBounce Type {4}",
    r.MailMessage.To[0].Address, r.MailMessage.From[0].Address, r.Addresses, r.BounceCategory, r.BounceType);

    // If it contains attachments.
    if (r.MailMessage.Attachments.Count > 0)
    {
        foreach (Attachment at in r.MailMessage.Attachments)
        {
            // Try to find the orginal message.
            if (at.FileName.EndsWith(".eml", StringComparison.InvariantCultureIgnoreCase))
            {
                // Create a new MailMessage object from the attachment.
                MailMessage msg = new MailMessage(at.GetContentStream());
                // Print out all name value pairs in the message headers.
                foreach (Header header in msg.Headers)
                {
                    Console.WriteLine("Header Name: {0}, Value: {1}", header.Name, header.Raw);
                    // Do something here.
                    // ...
                }
            }
        }
    }
}
else
    Console.WriteLine("No bounce information found");
' Create a new instance of the BounceInspector class.
Dim inspector As New BounceInspector()
' Process an EML file (you should change the file name here).
Dim r As BounceResult = inspector.Process("C:\ComponentPro\NetProducts\Branches\2009v4\UltimateBounceInspector\UnitTest\Data\FB043DC5B1CC4DD092056CEE1E47AEC9.eml")

' If this message was identified as a bounced email message.
If r.Identified Then
    Console.WriteLine("To E-mail: {0}" & vbCrLf & "From E-mail: {1}" & vbCrLf & "Bounced E-mail: {2}" & vbCrLf & "Bounce Category: {3}" & vbCrLf & "Bounce Type {4}", r.MailMessage.To(0).Address, r.MailMessage.From(0).Address, r.Addresses, r.BounceCategory, r.BounceType)

    ' If it contains attachments.
    If r.MailMessage.Attachments.Count > 0 Then
        For Each at As Attachment In r.MailMessage.Attachments
            ' Try to find the orginal message.
            If at.FileName.EndsWith(".eml", StringComparison.InvariantCultureIgnoreCase) Then
                ' Create a new MailMessage object from the attachment.
                Dim msg As New MailMessage(at.GetContentStream())
                ' Print out all name value pairs in the message headers.
                For Each header As Header In msg.Headers
                    Console.WriteLine("Header Name: {0}, Value: {1}", header.Name, header.Raw)
                    ' Do something here.
                    ' ...
                Next header
            End If
        Next at
    End If
Else
    Console.WriteLine("No bounce information found")
End If

Add a custom signature

The following example illustrates how to use AddBounceSignature to add a custom signature to BounceInspector.

Use asynchronous methods

BounceInspector class provides a number of methods allowing you to asynchronously connect, login, upload, download, etc. Their names always end with Async. This means the method will begin some operation on a new thread and immediately return to the caller. When the operation has completed, the corresponding event will be raised notifying you that the operation has completed and in the event handler method you can check for the error and use the result, if provided.

The example following demonstrates how to process a message asynchronously:

try
{
    // Create a new instance of the BounceInspector class.
    BounceInspector inspector = new BounceInspector();

    // Asynchronously process a single EML file.
    BounceResult r = await inspector.ProcessAsync("c:\\temp\\my eml.eml");

    // ...

    // If this message was identified as a bounced email message.
    if (r.Identified)
        Console.WriteLine(
            "To E-mail: {0}\r\nFrom E-mail: {1}\r\nBounced E-mail: {2}\r\nBounce Category: {3}\r\nBounce Type {4}",
            r.MailMessage.To[0].Address, r.MailMessage.From[0].Address, r.Addresses, r.BounceCategory,
            r.BounceType);
    else
        Console.WriteLine("No bounce information found");
}
catch (Exception exc)
{
    Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
}
Try
    ' Create a new instance of the BounceInspector class.
    Dim inspector As New BounceInspector()

    ' Asynchronously process a single EML file.
    Dim r As BounceResult = Await inspector.ProcessAsync("c:\temp\my eml.eml")

    ' ...

    ' If this message was identified as a bounced email message.
    If r.Identified Then
        Console.WriteLine("To E-mail: {0}" & vbCrLf & "From E-mail: {1}" & vbCrLf & "Bounced E-mail: {2}" & vbCrLf & "Bounce Category: {3}" & vbCrLf & "Bounce Type {4}", r.MailMessage.To(0).Address, r.MailMessage.From(0).Address, r.Addresses, r.BounceCategory, r.BounceType)
    Else
        Console.WriteLine("No bounce information found")
    End If
Catch exc As Exception
    Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
End Try
static void Main()
{
    // Create a new instance of the BounceInspector class.
    BounceInspector inspector = new BounceInspector();

    // Register an event handler.
    inspector.Processed += inspector_Processed;

    // Process all EML files in directory 'c:\\temp'.
    BounceResultCollection result = inspector.ProcessMessages("c:\\temp");

    // Display processed emails.
    foreach (BounceResult r in result)
    {
        // If this message was identified as a bounced email message.
        if (r.Identified)
        {
            // Print out the result
            Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\n" +
                          "Bounce Category: {3}\n" +
                          "Bounce Type: {4}\nDeleted: {5}\n" +
                          "DSN Action: {6}\n" +
                          "DSN Diagnostic Code: {7}\n\n",
                          System.IO.Path.GetFileName(r.FilePath),
                          r.MailMessage.Subject,
                          r.Addresses[0],
                          r.BounceCategory.Name,
                          r.BounceType.Name,
                          r.FileDeleted,
                          r.Dsn.Action,
                          r.Dsn.DiagnosticCode);
        }
    }

    Console.WriteLine("{0} bounced message found", result.BounceCount);
}

private static int _count;
static void inspector_Processed(object sender, ProcessedEventArgs e)
{
    _count++;
    // Only process 10 mail messages.
    if (_count == 10)
    {
        ((BounceInspector)sender).Cancel();
    }
}
Shared Sub Main()
    ' Create a new instance of the BounceInspector class.
    Dim inspector As New BounceInspector()

    ' Register an event handler.
    AddHandler inspector.Processed, AddressOf inspector_Processed

    ' Process all EML files in directory 'c:\\temp'.
    Dim result As BounceResultCollection = inspector.ProcessMessages("c:\temp")

    ' Display processed emails.
    For Each r As BounceResult In result
        ' If this message was identified as a bounced email message.
        If r.Identified Then
            ' Print out the result
            Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
        End If
    Next r

    Console.WriteLine("{0} bounced message found", result.BounceCount)
End Sub

Private Shared _count As Integer
Private Shared Sub inspector_Processed(ByVal sender As Object, ByVal e As ProcessedEventArgs)
    _count += 1
    ' Only process 10 mail messages.
    If _count = 10 Then
        CType(sender, BounceInspector).Cancel()
    End If
End Sub

Cancel an operation

To abort any transfer (downloading or uploading message) in progress you can either call the Cancel method or simply close the connection by calling the Disconnect or DisconnectAsync method.

Display progress while transferring data

When there are too many mail messages to process and your application may take time to process all of them, you may wish to show the progress of the validation to the user. The UltimateBounceInspector component provides progress notification through the Progress event. The Progress event is raised periodically while e-mail validation is in progress, making accessible necessary data to display progress information, such as e-mail address and validation level.

The following steps show you how to use the Progress event to show progress information while validating e-mail addresses:

static void Main()
{
    try
    {
        // Create a new instance of the BounceInspector class.
        BounceInspector inspector = new BounceInspector();

        // Register an event handler.
        inspector.Progress += inspector_Progress;

        // Process all EML files in directory 'c:\\temp'.
        BounceResultCollection result = inspector.ProcessMessages("c:\\temp");

        // Display processed emails.
        foreach (BounceResult r in result)
        {
            // If this message was identified as a bounced email message.
            if (r.Identified)
            {
                // Print out the result
                Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                                System.IO.Path.GetFileName(r.FilePath),
                                r.MailMessage.Subject,
                                r.Addresses[0],
                                r.BounceCategory.Name,
                                r.BounceType.Name,
                                r.FileDeleted,
                                r.Dsn.Action,
                                r.Dsn.DiagnosticCode);
            }
        }

        Console.WriteLine("{0} bounced message found", result.BounceCount);
    }
    catch (Exception exc)
    {
        Console.WriteLine(string.Format("An error occurred: {0}", exc.Message));
    }
}

/// <summary>
/// Handles the BounceInspector's Progress event.
/// </summary>
/// <param name="sender">The BounceInspector object.</param>
/// <param name="e">The event arguments.</param>
static void inspector_Progress(object sender, ProgressEventArgs e)
{
    Console.WriteLine("{0}/{1} message(s) processed, {2}% completed", e.Current, e.Total, e.Percentage);
}
Shared Sub Main()
    Try
        ' Create a new instance of the BounceInspector class.
        Dim inspector As New BounceInspector()

        ' Register an event handler.
        AddHandler inspector.Progress, AddressOf inspector_Progress

        ' Process all EML files in directory 'c:\\temp'.
        Dim result As BounceResultCollection = inspector.ProcessMessages("c:\temp")

        ' Display processed emails.
        For Each r As BounceResult In result
            ' If this message was identified as a bounced email message.
            If r.Identified Then
                ' Print out the result
                Console.Write("FileName: {0}" & vbLf & "Subject: {1}" & vbLf & "Address: {2}" & vbLf & "Bounce Category: {3}" & vbLf & "Bounce Type: {4}" & vbLf & "Deleted: {5}" & vbLf & "DSN Action: {6}" & vbLf & "DSN Diagnostic Code: {7}" & vbLf & vbLf, System.IO.Path.GetFileName(r.FilePath), r.MailMessage.Subject, r.Addresses(0), r.BounceCategory.Name, r.BounceType.Name, r.FileDeleted, r.Dsn.Action, r.Dsn.DiagnosticCode)
            End If
        Next r

        Console.WriteLine("{0} bounced message found", result.BounceCount)
    Catch exc As Exception
        Console.WriteLine(String.Format("An error occurred: {0}", exc.Message))
    End Try
End Sub

''' <summary>
''' Handles the BounceInspector's Progress event.
''' </summary>
''' <param name="sender">The BounceInspector object.</param>
''' <param name="e">The event arguments.</param>
Private Shared Sub inspector_Progress(ByVal sender As Object, ByVal e As ProgressEventArgs)
    Console.WriteLine("{0}/{1} message(s) processed, {2}% completed", e.Current, e.Total, e.Percentage)
End Sub