1

いくつかのメールボックスを監視するアプリを作成しようとしています。メールが見つかったら、各アイテムから情報を取得し、アイテムのリストを取得したら、適切なアクションを実行できます。

しかし、どのようにアプローチしても、Exchange が強制する 255 RPC 接続の制限に達しています。

エラーの原因については完全に行き詰まっています-私が見る限り、すべてが1つのメソッドに結び付けられており、Marshal.ReleaseComObjectを呼び出しています....開くことのパフォーマンスへの影響さえ受け入れていますOutlook アプリケーション ハンドル自体を閉じます。

どんなアドバイスでも大歓迎です...(プレビューでコードが間違っているように見える理由がわからないので、安全のためにペーストビンにも入れました... http://pastebin.com/m637eb95 )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop;
using System.Runtime.InteropServices;

namespace HandleMailingResponses
{
    class OutlookFolderTableScraper
    {
        public List<OutlookItem> GetItemsFromFolder(string folderName)
        {
            List<OutlookItem> returnList = new List<OutlookItem>();

            Application outlookHandle = new Application();
            NameSpace outlookNamespace = outlookHandle.GetNamespace("MAPI");
            Folders rootOutlookFolders = outlookNamespace.Folders;

            outlookNamespace.Logon(null, null, null, true);

            Folder requestedRoot = enumerateFolders(rootOutlookFolders, folderName);
            Folders theseFolders = requestedRoot.Folders;
            Folder thisInbox = enumerateFolders(theseFolders, "Inbox");

            Marshal.ReleaseComObject(requestedRoot);
            requestedRoot = null;
            Marshal.ReleaseComObject(rootOutlookFolders);
            rootOutlookFolders = null;

            string storeID = thisInbox.StoreID;

            Table thisTable = thisInbox.GetTable("",OlTableContents.olUserItems);

            //By default each item has the columns EntryID, Subject, CreationTime, LastModificationTime and MessageClass
            //we can add any of the other properties the MailItem or ReportItem object would have....
            Columns theseColumns = thisTable.Columns;
            theseColumns.Add("SenderEmailAddress");

            Marshal.ReleaseComObject(thisInbox);
            thisInbox = null;

            outlookNamespace.Logoff();
            Marshal.ReleaseComObject(outlookNamespace);
            outlookNamespace = null;
            outlookHandle.Quit();
            Marshal.ReleaseComObject(outlookHandle);
            outlookHandle = null;

            int count = 0;
            while (!thisTable.EndOfTable)
            {
                Row thisRow = thisTable.GetNextRow();
                object[] theseValues = (object[]) thisRow.GetValues();
                Console.WriteLine("processed {0}",count++);

                //get the body from this item
                string messageClass = (string)theseValues[4];
                string entryID = (string)theseValues[0];
                string body = getItemBody(entryID,storeID, messageClass);

                returnList.Add(new OutlookItem((string)theseValues[5], (string)theseValues[1], body, messageClass, entryID));
            }



            return returnList;
        }

        private string getItemBody(string entryID, string storeID, string messageClass)
        {
            Application outlookHandle = new Application();
            NameSpace outlookNamespace = outlookHandle.GetNamespace("MAPI");
            outlookNamespace.Logon(null, null, null, true);
            string body;

            if (messageClass.ToLower().StartsWith("report"))
            {
                ReportItem thisItem = (ReportItem)outlookNamespace.GetItemFromID(entryID, storeID);
                body = thisItem.Body;
                thisItem.Close(OlInspectorClose.olDiscard);
                //release this com reference
                int releaseResult;
                do
                {
                    releaseResult = Marshal.ReleaseComObject(thisItem);
                } while (releaseResult != 0);
            }
            else
            {
                MailItem thisItem = (MailItem)outlookNamespace.GetItemFromID(entryID, storeID);
                body = thisItem.Body;
                thisItem.Close(OlInspectorClose.olDiscard);
                //release this com reference
                int releaseResult;
                do
                {
                    releaseResult = Marshal.ReleaseComObject(thisItem);
                } while (releaseResult != 0);
            }

            outlookNamespace.Logoff();
            outlookNamespace = null;
            outlookHandle.Quit();
            outlookHandle = null;


            GC.Collect();
            GC.WaitForPendingFinalizers();

            return body;
        }

                    /// <summary>
        /// Iterates through an Outlook.Folders object searching for a folder with the given name
        /// </summary>
        /// <param name="rootFolder">An Outlook.Folder object</param>
        /// <param name="targetFolder"></param>
        /// <returns></returns>
        private Folder enumerateFolders(Folders rootFolders, string targetFolder)
        {
            Folder returnFolder = null;
            System.Collections.IEnumerator thisEnumerator = rootFolders.GetEnumerator();
            while (thisEnumerator.MoveNext())
            {
                Folder f = (Folder)thisEnumerator.Current;
                string name = f.Name;
                if (targetFolder.ToLower().Equals(name.ToLower()))
                {
                    returnFolder = f;
                    break;
                }
            }
            ICustomAdapter adapter = (ICustomAdapter)thisEnumerator;
            Marshal.ReleaseComObject(adapter.GetUnderlyingObject());
            adapter = null;
            return returnFolder;
        }
        }

}
4

1 に答える 1

0

関数を呼び出すたびに新しい Application オブジェクトを作成しないでください。不要になるまでクラスのプライベート メンバー変数として保持してください。そうすれば、コンストラクターで Namespace.Logon を呼び出すだけで済みます。

于 2010-01-27T00:49:01.917 に答える