I am trying to read the emails from a shared mailbox which has multiple folders and files. But I get the below mentioned error and the application completes the task without returning any data.
Error message: error
Here is the method where the application stops working according to the logs:
private bool IsAvailable(ChartData data, out string avilableFileName)
{
Log.Information("3. Checking if folders and files are Available");
foreach (MAPIFolder folder in mAPIFolder.Folders)
{
if (folder.FullFolderPath.Contains(data.MailFolder))
{
var mailfolder = data.MailFolder;
myfolder=outlookNameSpace.Folders["email"].
Folders["Inbox"].Folders["reports"].Folders[mailfolder];
break;
}
}
Log.Information("4. Checking if Creation Time > Received Time");
avilableFileName = string.Empty;
Items mailItems = myfolder.Items;
mailItems.Sort("ReceivedTime", true);
foreach (Object item in mailItems)
{
if (item is MailItem)
{
MailItem mailItem = (MailItem)item;
if (mailItem.CreationTime > data.LastRun)
{
Log.Information("5. CreationTime > LastRun...");
foreach (var attachment in mailItem.Attachments)
{
if (attachment is Attachment)
{
var attach = (Attachment)attachment;
string attachmentName = attach.FileName;
if (attachmentName.ToLower().Contains(data.Attachmentname.ToLower())
&& attachmentName.ToLower().EndsWith
(data.AttachmentExtension.ToLower()))
{
Log.Information($"6. Attachment Name: {attachmentName}");
avilableFileName = attachmentName;
return true;
}
}
}
}
}
}
return false;
}
This method is executed 200 times to check the availability of different filenames. This is how logs look at the end:
2023-04-25 17:52:30.829 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:30.911 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:31.013 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:31.086 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:31.157 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:31.232 +08:00 [INF] 5. CreationTime > LastRun...
2023-04-25 17:52:31.343 +08:00 [INF] 5. CreationTime > LastRun...
How can I optimize it or fix it so that my outlook does not lag and it is able to check the files availability successfully.?
Do not use foreach
loop - it keeps all collection elements referenced. Use a for
loop, avoid multiple dot notation, and release the objects using Marshal.ReleaseComObject
as soon as you are done.
Most importantly, never loop through all items in a folder. use Items.Find/FindNext
or Items.Restrict.
At the very least, use should use a restriction on CreationTime
. OOM does not allow to create restriction on attachment names, you'd need to use Redemption for that (I am its author).
for (int i = 1; i <= mailItems.Count; i++)
{
object item = mailItems[i];
if (item is MailItem mailItem)
{
if (mailItem.CreationTime > data.LastRun)
{
Log.Information("5. CreationTime > LastRun...");
var attachments = mailItem.Attachments;
for(int j = 1; j <= attachments.Count; j++)
{
var attach = attachments[j];
string attachmentName = attach.FileName;
if (attachmentName.ToLower().Contains(data.Attachmentname.ToLower())
&& attachmentName.ToLower().EndsWith
(data.AttachmentExtension.ToLower()))
{
Log.Information($"6. Attachment Name: {attachmentName}");
avilableFileName = attachmentName;
return true;
}
Marshal.ReleaseComObject(attach);
}
Marshal.ReleaseComObject(attachments);
}
Marshal.ReleaseComObject(mailItem)
}
Marshal.ReleaseComObject(item)
}