Also, there are only 20 messages in the PST.
PersonalStorage pst = PersonalStorage.FromFile(“2Speed.pst”);<o:p></o:p>
FolderInfo fi = pst.RootFolder.GetSubFolder("Test");
PersonalStorageQueryBuilder builder = new PersonalStorageQueryBuilder();
builder.SentDate.Since(new DateTime(1970, 1, 1));
Console.WriteLine("Builder start: " + DateTime.Now);
MessageInfoCollection coll = fi.GetContents(builder.GetQuery());
Console.WriteLine("\nTotal Messages: " + coll.Count);
Console.WriteLine("\nBuilder end: " + DateTime.Now);
Console.WriteLine("\nExtraction start: " + DateTime.Now);
int iCount = 0;
foreach (MessageInfo messageInfo in fi.EnumerateMessages())
using (FileStream fs = File.OpenWrite(iCount + ".msg"))
iCount += 1;
Console.WriteLine("\nExtraction end: " + DateTime.Now);
I would like to point out that the original poster is calling pst.ExtractMessage() rather than saving to a stream.
I have noticed similar issues. I have a program that scans PSTs loading and processing MapiMessage instances. By far the longest time is spent on the ExtractMessage() method. We are seeing speeds between 1 and 8 calls per second.
This wouldn’t be too bad if we could use multi-threading, but ExtractMessage fails if used without a lock in a C# Parallel.For loop.
We have considered using folderInfo.EnumerateMapiMessages() but that seems just as slow.
Is there any way to either load MapiMessage instances faster or load them in parallel?
I ran some tests on a PST using different methods to iterate over a PST. As can be seen below, the first method takes 10 seconds to iterate over the PST where the other methods take over 19 minutes. The first method uses MessageInfo instances while the other 2 use MapiMessages. Unfortunately we need to use MapiMessages.
Method 1: 9504 messages, 0 errors, 00:00:10
Method 2: 9504 messages, 0 errors, 00:19:28
Method 3: 9504 messages, 0 errors, 00:19:32
A cut down description of the code follows:
messageInfoCollection = folderInfo.GetContents();
for (var itemIndex = 1; itemIndex <= messageInfoCollection.Count; itemIndex++)
var mailItem = messageInfoCollection[itemIndex - 1];
var subject = mailItem.Subject;
mapiMessages = folderInfo.EnumerateMapiMessages();
foreach (MapiMessage msg in mapiMessages)
string subject = msg.Subject;
entryIds = folderInfo.EnumerateMessagesEntryId();
foreach (var entryId in entryIds)
var extractMessage = pst.ExtractMessage(entryId);
var subject = extractMessage.Subject;
Thank you for the detailed analysis.
The very first thing, that I would like to share, is that the API doesn’t support extracting messages in parallel/multi-threaded code. We already have a feature request logged as EMAILNET-33470 in our issue tracking system for implementation of this feature. However, it is still unresolved and yet to be considered by product team for possible implementation.
Unfortunately, as per your requirements, you have to use the ExtractMessage method as it is the only way to get the MapiMessage for usage. MessageInfo actually retrieves a subset of informaiton contained in the message and, hence, retrieval of such information is fast. At present, until EMAILNET-33470 is resolved, there seems to be no other way to extract messages more faster. Please feel free to share your feedback if any in this regard.
Hi, do you have any more information about when EMAILNET-33470 might be addressed? Thanks.