返回"使用" VAR

时间:2018-04-02 21:35:07

标签: c# asp.net memorystream

我需要返回一个MemoryStream,目前我这样做:

String ICallbackEventHandler.GetCallbackResult()
{

    using (var stream = new MemoryStream())
    {
        this._synth.Rate = this.Rate;
        this._synth.Volume = this.Volume;
        this._synth.SetOutputToWaveStream(stream);

        string sText = this.Context.Items["data"].ToString();
        this._synth.Speak(sText);

        //rewind to beginning of stream
        stream.Seek(0, SeekOrigin.Begin);

        using (var nMp3Stream = new MemoryStream())
        using (var rdr = new WaveFileReader(stream))
        using (var wtr = new LameMP3FileWriter(nMp3Stream, rdr.WaveFormat, LAMEPreset.STANDARD))
        {
            rdr.CopyTo(wtr);
            nMp3Stream.Position = 0;

            return (String.Concat("data:audio/mpeg;base64,", Convert.ToBase64String(nMp3Stream.ToArray())));
        }
    }
}

但我不认为这是正确的方法。我想我不应该返回using变量,对吧?

如果没有,我怎么能这样做?我想,我需要处理MemoryStream。我应该什么时候这样做,还是应该让GC做到这一点?

2 个答案:

答案 0 :(得分:1)

  

我想我不应该返回一个使用变量,对吧?

你不会使用var"返回"一点都不 您将其内容转换为字符串,然后返回该字符串。

using

在此处创建 return (String.Concat("data:audio/mpeg;base64,", Convert.ToBase64String(nMp3Stream.ToArray()))); 的新实例,并使用string的内容填充该实例并返回该实例。

  

我认为我需要处理MemoryStream。

是的,您必须考虑实例的生命周期。

  

我应该什么时候这样做,还是应该让GC这样做?

在大多数情况下,

但是,很大程度上取决于您的具体应用程序设计和执行动态。 例如:

  • 考虑将内存流转换为MemoryStream
  • 的性能影响
  • 考虑到转换时您分配了近2倍的内存:string另一个用于MemoryStream

答案 1 :(得分:0)

您实际上并未在此代码中返回using变量。 ToArray()调用创建了一个新的数组对象,其内存与nMp3Stream对象分开。此外,Convert.ToBase64String()创建了一个与数组分开的新字符串对象,String.Concat()创建了另一个与第一个字符串分开的字符串。

因此,当我质疑这段代码的效率时,特别是当它与通过垃圾收集器大对象堆的地址耗尽相关时,它肯定不会遇到using的任何问题。

如果您对修复性能问题感兴趣,那么这是一个更大的问题,可能涉及首先改变此方法的使用方式。

对于您确实希望从方法返回using块的主题的情况,该模式通常是删除使用块,而是将该块移动到呼叫者,召集者。如果using主题需要更长的生命周期,可能作为类成员,那么应该编写类来实现IDisposable,因此类实例本身可以成为{{1}的主题阻止。