使用递归时编组C#com项
我使用C#中的SourceSafe COM对象(SourceSafeTypeLib)来自动化SourceSafe递归get(大型构建过程的一部分)。递归函数如下所示。如何确保在foreach循环中创建的所有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
/// <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);
}