2010-03-31 2 views
0

Я использую COM-объект SourceSafe (SourceSafeTypeLib) из C# для автоматизации рекурсивного get SourceSafe (часть более крупного процесса сборки). Рекурсивная функция показана ниже. Как я могу гарантировать, что все COM-объекты, созданные в цикле foreach, будут выпущены правильно?Элементы Marshalling C# 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); 
       } 

      } 

     } 

ответ

0

Если это короткая работающая программа, и нет ничего, чтобы «совершить» на стороне 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); 
}