Выделение элементов C # com при использовании рекурсии - PullRequest
0 голосов
/ 31 марта 2010

Я использую COM-объект SourceSafe (SourceSafeTypeLib) из C # для автоматизации рекурсивного получения SourceSafe (часть более крупного процесса сборки). Рекурсивная функция показана ниже. Как убедиться, что все объекты COM, созданные в цикле foreach, освобождаются правильно?

   /// <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);
                }

            }

        }

1 Ответ

0 голосов
/ 31 марта 2010

Если это коротко запущенная программа и нечего «коммитить» на стороне COM, то можно позволить им уйти, верить этому или нет. GC придет и правильно освободит интерфейсы, когда это будет необходимо.

Если это длительно работающая программа (например, серверный компонент или для ее выполнения требуются часы и часы), или вам необходимо «зафиксировать» или «сохранить» изменения, лучшим вариантом будет выпустить их так же, как и любой другой VSSItem. после вызова GetChangedFiles(fileItem); в цикле foreach.

Пример:

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