C#:foreach循环到for循环COM.net编程泄漏的Outlook项目

C#:foreach循环到for循环COM.net编程泄漏的Outlook项目,c#,vsto,C#,Vsto,全部。在无缓存Exchange模式下运行Outlook 2010加载项时遇到问题。似乎你可以拨打多少电话来交换是有限制的。从这一点上,我的同事们相信,如果我们处理好所有的泄漏问题,那么就不会有任何问题。因此,我有一个函数返回用foreach循环编写的IEnumerable。我尝试将其转换为for循环,但无论它有多深,我都无法获得我想要的所有文件夹,而且奇怪的是,我需要以1开始计数,否则我会得到一个索引越界错误。有人能看看我的for循环,告诉我为什么它不能从根文件夹中获取所有子文件夹吗?例如,使用

全部。在无缓存Exchange模式下运行Outlook 2010加载项时遇到问题。似乎你可以拨打多少电话来交换是有限制的。从这一点上,我的同事们相信,如果我们处理好所有的泄漏问题,那么就不会有任何问题。因此,我有一个函数返回用foreach循环编写的IEnumerable。我尝试将其转换为for循环,但无论它有多深,我都无法获得我想要的所有文件夹,而且奇怪的是,我需要以1开始计数,否则我会得到一个索引越界错误。有人能看看我的for循环,告诉我为什么它不能从根文件夹中获取所有子文件夹吗?例如,使用foreach循环,我可以获得folderA、folderB和folderC以及folderC中的所有子文件夹,但是使用For循环,我只能获得folderA、folderB和folderC

Foreach循环:

private static IEnumerable<Outlook.Folder> getChildFolders(Outlook.Folder rootFolder, string folderToSkip)
    {
        foreach (Outlook.Folder t in rootFolder.Folders)
        {
            if (t.Name.Equals(folderToSkip) && !String.IsNullOrEmpty(folderToSkip))
            {
                continue;
            }
            yield return t;
            foreach (Outlook.Folder i in getChildFolders(t, folderToSkip)) { yield return i; }
        }           
    }
私有静态IEnumerable getChildFolders(Outlook.Folder rootFolder,string folderToSkip)
{
foreach(rootFolder.Folders中的Outlook.Folder t)
{
if(t.Name.Equals(folderToSkip)和&!String.IsNullOrEmpty(folderToSkip))
{
继续;
}
收益率t;
foreach(getChildFolders(t,folderToSkip)中的Outlook.Folder i){yield return i;}
}           
}
For循环:

对于(int count=1;rootFolder.Folders.count>count;count++) { if(rootFolder.Folders[count].Name.Equals(folderToSkip)和&!String.IsNullOrEmpty(folderToSkip)) { 继续; } var t=rootFolder.Folders[计数]为Outlook.Folder; 收益率t

            for (int i = 1; t.Folders.Count > i; i++)
            {
                var f = getChildFolders(t, folderToSkip).OfType<Outlook.Folder>().ToList()[i] as Outlook.Folder;
                yield return f;
            }
        }                  
for(int i=1;t.Folders.Count>i;i++)
{
var f=getChildFolders(t,folderToSkip).OfType().ToList()[i]作为Outlook.Folder;
收益率f;
}
}                  

我并不认为foreach循环会在Outlook中造成任何泄漏问题。我尝试了第二个类似上面的for循环,但仍然无法正确运行。我真的很挣扎。有人能告诉我哪里出错了吗?

您的for循环没有得到子文件夹,因为您忘记了实现foreach循环中存在的递归。您将进入根级别,并获取根的所有子级,但随后它将停止。您需要递归地与每个子文件夹进行交互,以便一直向下钻取

编辑以添加:

注意这一行 foreach(getChildFolders中的Outlook.Folder i(t,folderToSkip)){yield return i;}


这就是您缺少的递归

关于泄漏,你是对的,你需要小心做任何形式的for循环

您想做什么,为什么需要所有文件夹的引用

如果你必须这样做,这就是你如何做到不泄漏

private static IEnumerable<Outlook.Folder> getChildFolders(Outlook.Folder rootFolder, string folderToSkip)
{
    FolderCollection folders;
    try
    {
        folders = rootFolder.Folders
        foreach (Outlook.Folder t in folders)
        {
            if (t.Name.Equals(folderToSkip) && !String.IsNullOrEmpty(folderToSkip))
                continue;

            yield return t;
            foreach (Outlook.Folder i in getChildFolders(t, folderToSkip)) { yield return i; }
        }
    }
    finally
    {
        if (folders != null && Marshal.IsComObject(folders))
            Marshal.ReleaseComObject(folders);
    }        
}
私有静态IEnumerable getChildFolders(Outlook.Folder rootFolder,string folderToSkip)
{
文件夹收集文件夹;
尝试
{
folders=rootFolder.folders
foreach(文件夹中的Outlook.t文件夹)
{
if(t.Name.Equals(folderToSkip)和&!String.IsNullOrEmpty(folderToSkip))
继续;
收益率t;
foreach(getChildFolders(t,folderToSkip)中的Outlook.Folder i){yield return i;}
}
}
最后
{
if(文件夹!=null&&Marshal.iscom对象(文件夹))
封送.释放对象(文件夹);
}        
}

然后,您必须对从该方法导入的所有文件夹调用Marshal.ReleaseComObject。

您能帮助我将第二个foreach循环转换为for循环吗?我仍然不知道如何在第二个foreach循环中使用for循环。我正在使用该函数返回我传入的任何文件夹中的所有子文件夹。我有一个Winform,它将在树中显示托管Exchange文件夹及其所有子文件夹。我也用它来找到我想要的任何子文件夹。这很公平。我曾试图在我的文章《阅读》中记录COM互操作的工作原理,您应该了解为什么会出现泄漏,以及如何避免泄漏,而不是具体的修复