none
Outlook Add-In performance issue RRS feed

  • Question

  • Hi there,

    I have a question regarding the Outlook Add-In Issue. I have a code for extracting the UNREAD Mail, then send to the SharePoint. BUT when I install the Outlook Add-In in my outlook, I found out the performance is pretty slow even though I just only five unread mail. so How should I sort it out.

    WILL

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
            {
                EnsurePathExists(Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder);
    
                string logFileName = DateTime.Now.ToString("yyyy-MM-dd") + " " + "TecturaLog.txt";
    
                if (!File.Exists(Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder + "\\" + logFileName))
                {
                    using (FileStream fs = File.Create(Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder + "\\" + logFileName))
                    {}
                }
    
                Logging.LogFileName = Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder + "\\" + logFileName;
                Logging.WriteInformation("--------------------------------------------------------------------------");
                Logging.WriteInformation("[" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + "] LOGGER INITIALIZED on " + DateTime.Now.ToShortDateString());
                Logging.WriteInformation("--------------------------------------------------------------------------");
    
                Outlook.MAPIFolder outlookRootFolder = this.Application.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    
                try
                {
                    var t = Task.Run(() => EnumerateFolders(outlookRootFolder));
                    t.Wait();
                }
                catch (Exception eX)
                {
                    Logging.WriteError(eX.Message);
                }
    
                this.Application.ItemSend += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
            }
    
            #endregion
    
            private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
            {
                // Note: Outlook no longer raises this event. If you have code that 
                //    must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
            }
       
    
            #region STEP.1 : Go through the Folder Hierachy in the Outlook Application and to chech how many mail item is UNREAD
    
            // Uses recursion to enumerate Outlook subfolders.
            private void EnumerateFolders(Outlook.MAPIFolder CurrentFolder)
            {
                Outlook.Folders childFolders = CurrentFolder.Folders;
    
                // Call EnumerateFolders using childFolder.
                Save2MSG(CurrentFolder);
    
                if (childFolders.Count > 0)
                {
                    foreach (Outlook.Folder childFolder in childFolders)
                    {
                        Save2MSG(childFolder);
                        EnumerateFolders(childFolder);
                    }
                }
            }
    
            #endregion
    
            #region STEP.2 : Get the Mail Item from Outlook Application, to save it, then call SharePoint Web Service to put into the D365
    
            /// <summary>
            /// </summary>
            /// <param name="CurrentFolder"></param>
            private void Save2MSG(Outlook.MAPIFolder CurrentFolder)
            {
                Outlook.Items unreadItems = CurrentFolder.Items.Restrict("[Unread]=true");
    
                // Creates a new Outlook Application instance
                Outlook.Application outlookApplication = this.Application;
    
                // Creating a new Outlook message from the Outlook Application instance
                Outlook.MailItem mailItem = (Outlook.MailItem)(outlookApplication.CreateItem(Outlook.OlItemType.olMailItem));
    
                Logging.WriteInformation("Save2MSG -> outlookApplication.CreateItem -> true");
    
                for (int counter = 1; counter <= unreadItems.Count; counter++)
                {
                    try
                    {
                        dynamic unreadItem = CurrentFolder.Items[counter];
    
                        /// Set recipient information
                        /// 
                        mailItem.To = unreadItem.To;
                        Logging.WriteInformation("mailItem.To -> " + mailItem.To.ToString());
    
                        // Set the message subject
                        mailItem.Subject = unreadItem.Subject;
    
                        // Set some HTML text in the HTML body
                        mailItem.HTMLBody = unreadItem.HTMLBody;
    
                        // Save the MSG file in local disk
                        string mailSubject = unreadItem.Subject;
    
                        if (mailSubject.Contains(':')) mailSubject = mailSubject.Replace(':', '_');
                        Logging.WriteInformation("mailItem.Subject -> " + mailSubject);
    
                        // mailItem.UserProperties.Session.CurrentUser.Address
                        // "/o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=e0206acdf30143f9808dfda982abf1b2-will"
                        // DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss")
                        string msgFilePath = Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder + "\\" + mailSubject + ".msg";
                        Logging.WriteInformation("msgFilePath -> " + Properties.Settings.Default.Tectura_OutlookAddIn_TempFolder + "\\" + mailSubject + ".msg");
    
                        //mailItem.Save();
                        mailItem.SaveAs(msgFilePath, Outlook.OlSaveAsType.olMSG);
    
                        byte[] output = System.IO.File.ReadAllBytes(msgFilePath);
                        Logging.WriteInformation("CallTecturaWebService -> output -> " + output.Length);
    
                        CallTecturaWebService(output, unreadItem, msgFilePath);
    
                        TryToDelete(msgFilePath);
                        Logging.WriteInformation("TryToDelete -> " + msgFilePath + " -> true");
                    }
                    catch (Exception eX)
                    {
                        Logging.WriteError(eX.Message.ToString());
                    }
                }
            }
    
            #endregion


    Hi there, if you found my comment very helpful then please | Propose as answer | . Thanks and Regards.

    Thursday, July 18, 2019 5:51 AM

All replies

  • So which part / call / etc. takes the longest?

    Also, your code will not work - you retrieve unreadItems collection, but you never use it - the line

    dynamic unreadItem = CurrentFolder.Items[counter];

    must be

    dynamic unreadItem = unreadItems[counter];


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, July 18, 2019 1:45 PM
  • Hi Dmitry,

    the following image is a report by using vs .net performance profiler.


    Hi there, if you found my comment very helpful then please | Propose as answer | . Thanks and Regards.

    Thursday, July 18, 2019 2:25 PM
  • This really says nothing other than most time was spent in the OOM libraries. But you would expect that. You really need to do more per function or per linee performance evaluation.

    Also, you are accessing OOM on a secondary thread (Task.Run) - don't do that. Outlook will raise an exception as soon as it detects access on a secondary thread. I suspect that does not happen to you (yet) because you are running under the debugger (VS host process), so it is really out-of-proc.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, July 18, 2019 3:39 PM