I am following the example here (How to attach a file to work item in TFS without physical file path?) to attach a file to a work item in TFS, by having a stream instead of having a physical file. I have the following code:
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);
}
}
}
My question: During the assignment
attachment.LocalFile = stream;
Is stream copied to attachment.LocalFile by reference or by value? If it is copied by reference, I think the above code will not have a memory leak since it is disposing the stream in using:
using (MemoryStream stream = new MemoryStream()) { ... }
But if it copied by value(a copy of stream is made), this would leave a memory leak since FileAttachment is not being disposed, right? If memory leak is present, I think it is not possible to fix this memory leak since FileAttachment is not inheriting IDisposable. Below is the decompiled code resharper shows for 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;
}
}
}
}
How can we confirm whether the stream object is being copied by reference or by value? If it is copied by value, how can we stop the memory leak?