使用递归时编组 C# com 项目

发布于 2024-08-27 10:06:16 字数 2140 浏览 6 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零崎曲识 2024-09-03 10:06:16

如果它是一个运行时间较短的程序,并且 COM 端没有什么可“提交”的,那么无论你相信与否,就可以让它们离开。 GC会在需要的时候过来并正确释放接口。

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

例子:

foreach (VSSItem fileItem in vssItem.get_Items(false))
{
    GetChangedFiles(fileItem);
    // fileItem.Release(); or fileItem.Dispose();
    // or even Marshal.ReleaseComObject(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:

foreach (VSSItem fileItem in vssItem.get_Items(false))
{
    GetChangedFiles(fileItem);
    // fileItem.Release(); or fileItem.Dispose();
    // or even Marshal.ReleaseComObject(fileItem);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文