2016-04-26 4 views
1

Ich bin dem Beispiel hier (How to attach a file to work item in TFS without physical file path?) zum Anhängen einer Datei an ein Arbeitselement in TFS, indem Sie einen Stream anstelle einer physischen Datei haben . Ich habe den folgenden Code:C# Speichernutzung: Wert vs Referenztyp für Stream-Klassenverwendung in Team Foundation Server dlls

internal static void AddAttachment(WorkItemServer server, Project teamProject, string fileContent, WorkItem workItem) 
{ 
    FileAttachment attachment = new FileAttachment(); 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     using (StreamWriter writer = new StreamWriter(stream)) 
     { 
      writer.Write(fileContent); 
      writer.Flush(); 
      stream.Position = 0; 

      attachment.LocalFile = stream; 
      attachment.AreaNodeUri = ""; 
      attachment.FileNameGUID = Guid.NewGuid(); 
      attachment.ProjectUri = teamProject.Uri.ToString(); 

      server.UploadFile(attachment); 

      const string c_UpdatePackage = @"<validxml>"; 
      XmlDocument updatePackage = new XmlDocument(); 
      updatePackage.LoadXml(string.Format(c_UpdatePackage, workItem.Id /*work item ID*/, workItem.Rev /*work item latest revision*/, "Test attachment", attachment.FileNameGUID, DateTime.Now.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"), fileContent.Length, "John Smith", "http://localhost:8080/tfs/defaultcollection")); 

      XmlElement outputPackage; 
      string dbStamp; 
      IMetadataRowSets metadata; 
      server.Update(Guid.NewGuid().ToString(), updatePackage.DocumentElement, out outputPackage, null, out dbStamp, out metadata); 
     } 
    } 
} 

Meine Frage: Während der Zuordnung

attachment.LocalFile = stream; 

Strom durch Bezugnahme auf attachment.LocalFile kopiert oder von Wert? Wenn es durch Verweis kopiert wird, denke ich, der obige Code nicht ein Speicherleck haben, da sie den Strom trennt sich in Verwendung:

using (MemoryStream stream = new MemoryStream()) { ... } 

Aber wenn es von Wert kopiert (eine Kopie des Stroms wird), ist diese würde ein Speicherleck hinterlassen, da FileAttachment nicht entsorgt wird, oder? Wenn ein Speicherleck vorhanden ist, ist es meines Erachtens nicht möglich, dieses Speicherleck zu beheben, da FileAttachment IDisposable nicht erbt. Im Folgenden finden Sie die dekompiliert Code resharper Shows für Fileattachment:

namespace Microsoft.TeamFoundation.WorkItemTracking.Proxy 
{ 
    public struct FileAttachment 
    { 
     private Stream m_localFile; 
     ... 
     public Stream LocalFile 
     { 
      get 
      { 
       return this.m_localFile; 
      } 
      set 
      { 
       this.m_localFile = value; 
      } 
     } 
    } 
} 

Wie können wir, ob das Stream-Objekt bestätigen wird durch Verweis oder durch Wert kopiert? Wenn es nach Wert kopiert wird, wie können wir das Speicherleck stoppen?

+0

Objekte werden immer als Referenz kopiert. Primitive Typen werden nach Wert kopiert. So weißt du es. – JSON

Antwort

0

Ein Objekt ist ein Referenz-Typ, wenn es ein class ist und ein value type wenn es ein struct oder enumerable ist. FileAttachment ist ein class.

Daher führt die Zuweisung nicht zu einem Speicherverlust, da es sich um eine Kopie durch Referenzzuweisung handelt.

Es sollte auch beachtet werden, dass die attachment.LocalFile Eigenschaft, sobald es diesen Bereich using() verlässt, auf ungültige Daten zeigen, und eine Ausnahme auslöst, wenn irgendetwas versucht, auf diese Eigenschaft zuzugreifen.

+1

Ich habe überprüft, dass der Stream nicht lesbar ist, sobald ich den Anwendungsbereich 'using()' verlasse. Aber nur ein Problem. Sie haben in Ihrer Antwort erwähnt, dass FileAttachment eine 'Klasse' ist. Aber eigentlich ist es eine 'Struktur'. Ändert dies das Verhalten von 'FileAttachment.LocalFile'? – Romonov

+0

Ich vermute, Sie rollen Ihre eigene FileAttachment-Klasse? Wenn es eine Struktur ist, sollte es nichts ändern. Ein in einer Struktur enthaltener Referenztyp verhält sich wie jeder andere Referenztyp. Sehen Sie sich http://stackoverflow.com/a/945708/6137718 an. Veränderbare Felder innerhalb einer Struktur werden normalerweise als schlechte Praxis angesehen. – gnalck

+0

Die FileAttachment-Klasse stammt von Microsoft.TeamFoundation.WorkItemTracking.Proxy dll. – Romonov

Verwandte Themen