返回一个 "Using" 变量
Returning a "Using" var
我需要 return 一个 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())));
}
}
}
但我认为这不是正确的方法。我想我不应该 return 一个 using
变量,对吧?
如果没有,我该怎么做?我想我需要处理 MemoryStream。我应该什么时候做这个,或者我应该让 GC 做这个?
您实际上并没有在这段代码中 returning using
变量。 ToArray()
调用创建了一个新的数组对象,其内存与 nMp3Stream
对象分开。此外,Convert.ToBase64String()
创建了一个与数组分开的新字符串对象,并且 String.Concat()
创建了另一个与第一个字符串分开的字符串。
因此,虽然我质疑这段代码的效率,尤其是因为它与垃圾收集器大对象堆的地址耗尽有关,但它肯定不会 运行 出现 using
的任何问题。
如果您有兴趣解决性能问题,这是一个更大的问题,可能首先涉及更改此方法的使用方式。
对于您确实想要 return 方法中 using
块的主题的情况,模式通常是 删除 使用块,而是将该块移动到调用者。如果using
主体需要更长的生命周期,也许作为class成员,那么class应该写成实现IDisposable
,所以class 实例本身可以成为 using
块的主题。
I guess I shouldn't return a using variable, right?
你根本不会 return "using var"。
您将它的内容转换为 string ,然后 return 该字符串。
return (String.Concat("data:audio/mpeg;base64,",
Convert.ToBase64String(nMp3Stream.ToArray())));
在这里您创建 一个 string
的新 实例,用 MemoryStream
和 return 该实例的内容填充它。
I need to dispose the MemoryStream, I think.
是的,您必须考虑实例的生命周期。
When should I do this, or should I let the GC do this?
在大多数情况下,是 您 处理了它,并且您正在以正确的方式进行处理,至少从提供的代码示例来看是这样。
但是,很大程度上取决于您的具体应用程序设计和执行动态。
例如:
- 考虑将内存流转换为
string
的性能影响
- 考虑到在转换时您分配了几乎 2 倍的内存:一个用于
MemoryStream
另一个用于 string
我需要 return 一个 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())));
}
}
}
但我认为这不是正确的方法。我想我不应该 return 一个 using
变量,对吧?
如果没有,我该怎么做?我想我需要处理 MemoryStream。我应该什么时候做这个,或者我应该让 GC 做这个?
您实际上并没有在这段代码中 returning using
变量。 ToArray()
调用创建了一个新的数组对象,其内存与 nMp3Stream
对象分开。此外,Convert.ToBase64String()
创建了一个与数组分开的新字符串对象,并且 String.Concat()
创建了另一个与第一个字符串分开的字符串。
因此,虽然我质疑这段代码的效率,尤其是因为它与垃圾收集器大对象堆的地址耗尽有关,但它肯定不会 运行 出现 using
的任何问题。
如果您有兴趣解决性能问题,这是一个更大的问题,可能首先涉及更改此方法的使用方式。
对于您确实想要 return 方法中 using
块的主题的情况,模式通常是 删除 使用块,而是将该块移动到调用者。如果using
主体需要更长的生命周期,也许作为class成员,那么class应该写成实现IDisposable
,所以class 实例本身可以成为 using
块的主题。
I guess I shouldn't return a using variable, right?
你根本不会 return "using var"。 您将它的内容转换为 string ,然后 return 该字符串。
return (String.Concat("data:audio/mpeg;base64,",
Convert.ToBase64String(nMp3Stream.ToArray())));
在这里您创建 一个 string
的新 实例,用 MemoryStream
和 return 该实例的内容填充它。
I need to dispose the MemoryStream, I think.
是的,您必须考虑实例的生命周期。
When should I do this, or should I let the GC do this?
在大多数情况下,是 您 处理了它,并且您正在以正确的方式进行处理,至少从提供的代码示例来看是这样。
但是,很大程度上取决于您的具体应用程序设计和执行动态。 例如:
- 考虑将内存流转换为
string
的性能影响
- 考虑到在转换时您分配了几乎 2 倍的内存:一个用于
MemoryStream
另一个用于string