使用递归时编组C#com项

使用递归时编组C#com项,c#,com,visual-sourcesafe,C#,Com,Visual Sourcesafe,我使用C#中的SourceSafe COM对象(SourceSafeTypeLib)来自动化SourceSafe递归get(大型构建过程的一部分)。递归函数如下所示。如何确保在foreach循环中创建的所有COM对象都被正确释放 /// <summary> /// Recursively gets files/projects from SourceSafe (this is a recursive function). /// </sum

我使用C#中的SourceSafe COM对象(SourceSafeTypeLib)来自动化SourceSafe递归get(大型构建过程的一部分)。递归函数如下所示。如何确保在foreach循环中创建的所有COM对象都被正确释放

   /// <summary>
        /// Recursively gets files/projects from SourceSafe (this is a recursive function).
        /// </summary>
        /// <param name="vssItem">The VSSItem to get</param>
        private void GetChangedFiles(VSSItem vssItem)
        {

            //  'If the object is a file perform the diff,
            //  'If not, it is a project, so use recursion to go through it
            if(vssItem.Type == (int)VSSItemType.VSSITEM_FILE)
            {
                bool bDifferent = false; //file is different
                bool bNew = false; //file is new

                //Surround the diff in a try-catch block. If a file is new(doesn't exist on
                //the local filesystem) an error will be thrown.  Catch this error and record it
                //as a new file.
                try
                {
                    bDifferent = vssItem.get_IsDifferent(vssItem.LocalSpec);
                }
                catch
                {
                    //File doesn't exist
                    bDifferent = true;
                    bNew = true;
                }

                //If the File is different(or new), get it and log the message
                if(bDifferent)
                {
                    if(bNew)
                    {
                        clsLog.WriteLine("Getting " + vssItem.Spec);
                    }
                    else
                    {
                        clsLog.WriteLine("Replacing " + vssItem.Spec);
                    }

                    string strGetPath = vssItem.LocalSpec;
                    vssItem.Get(ref strGetPath, (int)VSSFlags.VSSFLAG_REPREPLACE);
                }

            }
            else //Item is a project, recurse through its sub items
            {
                foreach(VSSItem fileItem in vssItem.get_Items(false))
                {
                    GetChangedFiles(fileItem);
                }

            }

        }
//
///递归地从SourceSafe获取文件/项目(这是一个递归函数)。
/// 
///要获取的VSSItem
私有void GetChangedFiles(VSSItem-VSSItem)
{
//'如果对象是文件,则执行差异,
//'如果不是,则它是一个项目,因此使用递归遍历它
if(vssItem.Type==(int)VSSItemType.vssItem_文件)
{
bool bDifferent=false;//文件不同
bool bNew=false;//文件是新的
//在try-catch块中环绕差异。如果文件是新的(在上不存在)
//本地文件系统)将抛出错误。捕获此错误并记录它
//作为一个新文件。
尝试
{
bDifferent=vssItem.get_是不同的(vssItem.LocalSpec);
}
抓住
{
//文件不存在
b不同=正确;
bNew=真;
}
//如果文件不同(或新),则获取该文件并记录消息
如果(b不同)
{
如果(bNew)
{
clsLog.WriteLine(“获取”+vssItem.Spec);
}
其他的
{
clsLog.WriteLine(“替换”+vssItem.Spec);
}
字符串strGetPath=vssItem.LocalSpec;
获取(参考目标路径,(int)VSSFlags.VSSFLAG_REPREPLACE);
}
}
else//Item是一个项目,通过其子项递归
{
foreach(VSSItem.get_Items中的VSSItem fileItem(false))
{
GetChangedFile(文件项);
}
}
}

如果它是一个短时间运行的程序,并且在COM端没有什么可“提交”的,那么不管你信不信,让它们去吧。GC将在需要时来适当地释放接口

如果它是一个长时间运行的程序(如服务器组件或需要数小时才能完成),或者您需要“提交”或“保存”更改,那么最好的办法是在调用
GetChangedFiles(fileItem)后立即释放它们,就像释放任何VSSItem一样在foreach循环中

例如:

foreach (VSSItem fileItem in vssItem.get_Items(false))
{
    GetChangedFiles(fileItem);
    // fileItem.Release(); or fileItem.Dispose();
    // or even Marshal.ReleaseComObject(fileItem);
}