简体   繁体   English

C#内存使用情况:Team Foundation Server dll中流类使用的值与引用类型

[英]C# memory usage: value vs reference type for stream class usage in Team Foundation Server dlls

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. 我正在按照此处的示例( 如何将文件附加到TFS中没有物理文件路径的工作项? )将文件附加到TFS中的工作项,方法是使用流而不是物理文件。 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? 流是通过引用还是通过值复制到attachment.LocalFile? 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? 但是如果按值复制(流的副本被复制),由于FileAttachment没有被处理,这会留下内存泄漏,对吧? If memory leak is present, I think it is not possible to fix this memory leak since FileAttachment is not inheriting IDisposable. 如果存在内存泄漏,我认为无法修复此内存泄漏,因为FileAttachment不继承IDisposable。 Below is the decompiled code resharper shows for FileAttachment: 下面是FileAttachment的反编译代码resharper:

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? 如果按值复制,我们如何才能阻止内存泄漏?

An object is a reference type if it is a class , and a value type if it is a struct or enumerable . 一个对象是一个引用类型,如果它是一个class ,和一个值类型 ,如果它是一个structenumerable FileAttachment is a class . FileAttachment是一个class

As such, the assignment attachment.LocalFile = stream; 因此,赋值attachment.LocalFile = stream; does not result in a memory leak because it is a copy by reference assignment. 不会导致内存泄漏,因为它是引用分配的副本。

It should also be noted that the attachment.LocalFile property, once it exits that using() scope, will point to invalid data, and will throw an exception if anything attempts to access that property. 还应该注意的是, attachment.LocalFile属性一旦退出using()作用域,就会指向无效数据,并且如果有任何东西试图访问该属性,则会抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM