Pop3LastDownloadedMessages Property |
Namespace: MailBee.Pop3Mail
Note |
---|
This is an advanced property which serves special purposes. It's activated via setting EnableLastDownloaded prior to calling a method which requests mail messages from the server. |
This property can be used to get downloaded mail messages in the case if the corresponding method failed. Pop3 methods throw an exception or return a null reference on failure. Sometimes, however, the developer still wishes to get messages which had already been received to the moment of failure (for instance, if 100 messages had been received and error occurred for message #101). In this case, the developer can use this property to get messages which had already been received and parsed to the moment of the failure.
When this collection is not needed any longer, the developer should set EnableLastDownloaded to false to free the resources. Also, LastDownloadedMessages will be reset to a null reference with a new call of any method requesting mail messages from the server.
This sample demonstrates reliable approach to downloading messages from a POP3 account. The code tolerates disconnections and other errors which may occur during downloading messages. If any problem occurs, the code reconnects to the server if needed and attempts to download the remaining messages (already downloaded messages are not downloaded again, however). Also, the code execution won't end up in an endless loop in the case of permanent errors (if no messages had been downloaded at all, the code won't try again).
To simulate connection drops during the POP3 session, the code suddenly closes the connection during getting message data from the server.
using System; using MailBee; using MailBee.Mime; using MailBee.Pop3Mail; class Sample { static int traffic; static bool downloadingMsgs; // We use Pop3.DataReceived event to simulate connection drop during // getting message data from the server. We do this through closing // the connection after 50000 bytes of message data has been received from the // server. This may occur multiple times (for instance, if there is 1MB of mail // in the inbox, the connection will be dropped about 20 times). // If, however, there is a message larger than 50KB in the inbox, the download process // will stop because it would otherwise end up in an endless loop (because this code // always disconnects on getting 50-th KB of the data and it would never have received // such message completely). static void pop_DataReceived(object sender, DataTransferEventArgs e) { if (downloadingMsgs) { traffic += e.Data.Length; // Increase 50000 to a larger value if you wish to test this code with // a mailbox containing large messages (larger than 50KB). if (traffic > 50000) { ((Pop3)sender).Log.WriteLine("SIMULATE CONNECTION DROP"); ((Pop3)sender).GetSocket().Close(); } } } static void Main(string[] args) { // Initialize Pop3 object and make it automatically load UIDs of all messages on the server. Pop3 pop = new Pop3(); pop.InboxPreloadOptions = Pop3InboxPreloadOptions.Uidl; // Enable logging POP3 session into a file. Useful for troubleshooting. // Also, this log can be used to track the history of disconnections and // reconnections during downloading messages. pop.Log.Filename = @"C:\Temp\log.txt"; pop.Log.Enabled = true; pop.Log.Clear(); // Attach to a DataReceived event which will be used for simulating // connection failures. pop.DataReceived += new DataTransferEventHandler(pop_DataReceived); // Will set it to true once either everything has been downloaded // or a permanent error has occurred. bool finished = false; // Remember UID of the last message which had already been downloaded. // After reconnecting, we'll download messages with UIDs corresponding to // subsequent messages. For the first time, set it to null to indicate no // messages had already been downloaded. string lastUid = null; // We'll collect downloaded messages in this collection. MailMessageCollection msgs = new MailMessageCollection(); // Because we catch exceptions in this code but still want to know // which error has occurred in the case of permanent failure, we remember // the reason of it. MailBeeException permanentException = null; // Enable cache of messages downloaded during execution of the last method. pop.EnableLastDownloaded = true; do { // Prevent connection drop simulation when not downloading messages. downloadingMsgs = false; // Connect or reconnect to the server if required (and login/select inbox). if (!pop.IsConnected) { pop.Connect("pop.company.com"); } if (!pop.IsLoggedIn) { pop.Login("jdoe", "secret"); } traffic = 0; try { // Enable connection drop simulation. downloadingMsgs = true; int lastMsgNumber = 0; if (lastUid != null) { lastMsgNumber = pop.GetMessageIndexFromUid(lastUid); } if (lastMsgNumber < pop.InboxMessageCount) { // Download the remaining messages. pop.DownloadEntireMessages(lastMsgNumber + 1, -1); msgs.Add(pop.LastDownloadedMessages); } // Disable connection drop simulation. downloadingMsgs = false; // All's done. finished = true; } catch (MailBeeException e) { downloadingMsgs = false; if (pop.LastDownloadedMessages == null || pop.LastDownloadedMessages.Count == 0) { // Haven't got any messages. Assume this is permanent error // (otherwise, we could get endless loop). finished = true; permanentException = e; } else { // Error has occurred but some messages have still been // downloaded. We'll proceed with getting the rest of messages. msgs.Add(pop.LastDownloadedMessages); // Get last UID from the value of UID of the last downloaded message. lastUid = (string)pop.LastDownloadedMessages[pop.LastDownloadedMessages.Count - 1].UidOnServer; } } } while (!finished); // Clear and disable the cache of the last downloaded messages. pop.EnableLastDownloaded = false; if (pop.IsConnected) { // Attempt to disconnect (we need to catch MailBeeSocketObjectDisposedException // here because we simulated connection drop bypassing MailBee (using Socket.Close() // method) and Pop3.IsConnected could remain true). In real world apps, this // is not required and Pop3.IsConnected always reflects the actual state of // the connection. try { pop.Disconnect(); } catch (MailBeeSocketObjectDisposedException) {} } // Display UIDs of the downloaded messages. foreach (MailMessage msg in msgs) { Console.Write((string)msg.UidOnServer + " "); } } }