IMAP KeyNotFoundException when saving to memory stream

0 votes
asked Oct 24, 2012 by dandorey (120 points)
edited Nov 2, 2012

Hi,

I'm using Rebex Components 2012 R2 and I've created a service that will connect to multiple email servers. Each connection to an email server is handled by a seperate thread so we can pull emails at the same time.

I'm getting an error in an unexpect place when I'm downloading from more than one email server at the same time.

I'm able to retrieve the email headers and the actual email without problems. However when I try and write the email to a memory stream, I get the following exception thrown from the line:

mailMessage.Save(mailStream, MailFormat.OutlookMsg)

produces:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.

at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at 99RMJ.SWNpk.o6dmZZ(1eAI5d , BinaryWriter ) at 99RMJ.SWNpk.296drUZ(1eAI5d ) at 99RMJ.SWNpk.296drUZ(Stream ) at Rebex.Mail.MailMessage.pKu2tZ(Stream , MailFormat ) at Rebex.Mail.MailMessage.Save(Stream output, MailFormat format) at Routing.Common.EmailService.EmailConnection.DownloadMessage(ImapMessageInfo message)

Here is basically what I'm doing for each thread/connection:

var messageList = mImapConnection.GetMessageList(ImapMessageSet.All,
                                                ImapListFields.Flags | ImapListFields.UniqueId);

foreach (ImapMessageInfo curMessage in messageList.Where(m => !m.IsDeleted))
{
    MailMessage mailMessage = mImapConnection.GetMailMessage(message.UniqueId);
    var mailStream = new MemoryStream();
    mailMessage.Save(mailStream, MailFormat.OutlookMsg);
}

Note this is ONLY an issue when I'm connected to more than one email server at the same time. I'm creating a seperate instance of Imap for each connection and only have one thread for each connection.

Applies to: Rebex Secure Mail
commented Oct 25, 2012 by Lukas Pokorny (124,610 points)
edited Oct 25, 2012

This looks like a bug in MailMessage object's Save method (possibly in the MSG message writer). Thanks for bringing this to our attention, we will look into this !

1 Answer

0 votes
answered Oct 25, 2012 by Lukas Pokorny (124,610 points)
edited Nov 2, 2012

We have identified the bug. It's caused by a thread-unsafe dictionary initialization code in MSG message writer and sometimes occurs when calling multiple Save methods (on different objects) at the same time from multiple threads. We will fix this for Rebex Secure Mail 2012 R3 which should be released very soon. If you would like to get a beta when it's ready, please let us know!

Update: This was fixed in Rebex Secure Mail 2012 R3

commented Oct 25, 2012 by dandorey (120 points)
edited Nov 2, 2012

Thanks for the quick response.

Would I be able to work around this in some way? If I only call this method with a single thread at one time, will I be able to avoid this?

Thanks, Dan

commented Oct 25, 2012 by Lukas Pokorny (124,610 points)
edited Nov 2, 2012

Yes - add a private static object SaveSync = new object(); object to the class calling mailMessage.Save and put the Save call into lock (SaveSync) { mailMessage.Save(...); } block. That will ensure that the method won't be called from more threads at the same time. Please note that this is only necessary when using MailFormat.OutlookMsg.

commented Oct 25, 2012 by dandorey (120 points)
edited Nov 2, 2012

Hi,

Yes that appears to work without issue.

Thanks for your help!

...