EmailAddressValidatorBeginVerify Method |
Note: This API is now obsolete.
Namespace: MailBee.AddressCheck
[ObsoleteAttribute("This method is obsolete in .NET 4.5+. Use VerifyAsync instead.")] public IAsyncResult BeginVerify( DataTable emailsAsTable, IDataReader emailsAsReader, string columnName, AsyncCallback callback, Object state )
Exception | Condition |
---|---|
MailBeeInvalidArgumentException | Both emailsAsTable and emailsAsTable are a null reference (Nothing in Visual Basic), or columnName is a null reference or an empty string, or DnsServers collection is empty. |
Note |
---|
New applications (.NET 4.5+) should use async/await methods instead. The are more efficient and easier to use. |
If you set both emailsAsTable and emailsAsReader, emailsAsReader will be ignored.
If you have a string array of e-mails rather than a DataTable, you can use ArrayToDataTable(String) method to make conversion prior to calling this method.
This WinForms sample demonstrates using async e-mail verification process.
To run it, you'll need to create a WinForm app, put button1 on the form, in Form1 properties click FormClosed event to create its handler, click button1 to create its handler, then replace the Form1.cs/Form1.vb with the code below. C#-specific: the sample below is not wrapped into any namespace so you'll need to remove wrapping namespace from Form1.Designer.cs as well.
This sample also highlights some interesting aspects of multi-threaded and async programming of WinForms apps which are not directly related to MailBee but can help beginner progammers avoid common pitfalls.
using System; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using MailBee; using MailBee.AddressCheck; public partial class Form1 : Form { public Form1() { InitializeComponent(); } private EmailAddressValidator valid = null; private StreamWriter sw = null; // This method will be executed for each e-mail address in the bulk, // whenever it gets verified, with either positive or negative result. private void valid_Verified(object sender, VerifiedEventArgs e) { try { // Note that unlike Console version of this sample, which can be found in the documentation on // EmailAddressValidator.Verify(DataTable, string) method, we're not using lock here. This is // because in WinForms apps events are raised on a single thread (message loop thread), and this // eliminates the need to synchronize threads. If we were using Console or ASP.NET app, lock // (SyncLock in VB) would be required. Also, it's required if instead of using Verified event, // you inherited EmailAddressValidator class and overrided OnVerified method (such methods can // execute on any thread). sw.WriteLine(string.Format("{0}={1}", e.Email, e.Result.ToString())); } catch (Exception ex) { // This is also important. In multi-threaded mode, crashing due to an exception simply // closes the worker thread and you may never know what really happened. Thus, it's recommended // (at least in debug) to catch all exceptions there and print them out (here, alert window). MessageBox.Show(ex.ToString()); } } // As it's not allowed to make changes to UI (such as to update button text) directly in the callback // (it's Windows limitation) we need to dispatch the call to the message loop thread. private delegate void UpdateUserInterfaceDelegate(); private void UpdateUserInterface() { button1.Text = "Done"; } // This callback is executed when all addresses have been verified and all threads have been completed. private void VerifyCallback(IAsyncResult result) { try { // Callbacks can execute on any thread (see the comment in valid_Verified why this can be // important). However, we have only one callback, and it does not compete with other callbacks // for accessing thread-unsafe resources. If we had the code which can run multiple callbacks // simultaneously and the callback included the code used some shared resource (like the same // file to write to) we had to guard that code with lock (SyncLock in VB) in that case. valid.EndVerify(); // Another problem of callback's execution on any thread is that we cannot update user interface // from a callback. User interface updates must occur only on the main thread (message loop). // To workaround this, we're using Invoke which executes UI update on the message loop thread. Invoke(new UpdateUserInterfaceDelegate(UpdateUserInterface), null); } catch (MailBeeUserAbortException) { sw.WriteLine("Aborted by user"); } finally { sw.Close(); } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (valid != null) { // If the user wants to cancel and closes the app, abort things. valid.Abort(); } } private void button1_Click(object sender, EventArgs e) { if (valid != null && valid.IsBusy) { // No re-entrance while working. MessageBox.Show("Busy!"); return; } button1.Text = "Busy"; valid = new EmailAddressValidator("MN110-0123456789ABCDEF-0123"); // To perform DNS MX lookup queries, we need some DNS servers for that. valid.DnsServers.Autodetect(); // Logging into a file is not required for the component to work // but helpful for debugging and understanding things under the hood. // Since this sample is multi-threaded, we also set AddContextInfo option // to make it easier analyze the log (each record will be tagged with a thread ID). valid.Log.Enabled = true; valid.Log.Format = LogFormatOptions.AddContextInfo; valid.Log.Filename = @"C:\Temp\log.txt"; valid.Log.Clear(); // Subscribe to event. valid.Verified += new VerifiedEventHandler(valid_Verified); // In this sample, we'll build DataTable manually from a string array. string[] emails = new string[10]; for (int i = 0; i < emails.Length; i++) { // Make user0@domain0.com, user1@domain1.com, ..., user9@domain9.com. emails[i] = string.Format("user{0}@domain{0}.com", i.ToString()); } // In real apps, you'll get data from database. For now, populate data from // string array by putting all the data into a table with one column "email". DataTable data = valid.ArrayToDataTable(emails); // Enable as many threads as possible. valid.MaxThreadCount = -1; sw = new StreamWriter(@"C:\Temp\report.txt"); // Run the verification in multi-threaded mode, asynchronously. valid.BeginVerify(data, null, "email", new AsyncCallback(VerifyCallback), null); } }