2010-03-31 8 views
0

J'utilise l'objet SourceSafe COM (SourceSafeTypeLib) de C# pour automatiser un get SourceSafe récursif (partie d'un processus de génération plus important). La fonction récursive est montrée ci-dessous. Comment puis-je m'assurer que tous les objets COM créés dans la boucle foreach sont libérés correctement?Marquage des éléments C# com lors de l'utilisation de la récursivité

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

      } 

     } 

Répondre

0

S'il s'agit d'un programme court et qu'il n'y a rien à "commettre" du côté COM, vous pouvez le laisser partir, croyez-le ou non. Le GC viendra et libèrera correctement les interfaces quand il le faut. S'il s'agit d'un programme de longue durée (comme un composant de serveur ou prend des heures et des heures pour le terminer), ou si vous avez besoin de "valider" ou de "sauvegarder" des modifications, la meilleure solution serait de les libérer comme VSSItem juste après votre appel à GetChangedFiles(fileItem); dans votre boucle foreach.

Exemple:

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