使用递归时编组 C# com 项目
我正在使用 C# 中的 SourceSafe COM 对象 (SourceSafeTypeLib) 来自动执行 SourceSafe 递归获取(较大构建过程的一部分)。递归函数如下所示。如何确保在 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);
}
}
}
I am using the SourceSafe COM object (SourceSafeTypeLib) from C# to automate a SourceSafe recursive get (part of a larger build process). The recursive function is shown below. How do I ensure that all the COM objects created in the foreach loop get released correctly?
/// <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);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果它是一个运行时间较短的程序,并且 COM 端没有什么可“提交”的,那么无论你相信与否,就可以让它们离开。 GC会在需要的时候过来并正确释放接口。
如果它是一个长时间运行的程序(如服务器组件或需要数小时才能完成),或者您需要“提交”或“保存”更改,最好的选择是在调用后立即释放它们,就像释放任何 VSSItem 一样到 foreach 循环中的
GetChangedFiles(fileItem);
。例子:
If it is a short running program and there is nothing to "commit" on the COM side, it is ok to let them go, believe it or not. The GC will come and properly release the interfaces when it needs to.
If it is a long running program (like a server component or takes hours and hours to complete), or you need to "commit" or "save" changes the best bet would be to release them as you would any VSSItem right after your call to
GetChangedFiles(fileItem);
in your foreach loop.Example: