在IDisposable对象上使用语句 - 调用Dispose方法的延迟

psu*_*lek 7 c# idisposable using-statement

正如本文所述,关于在IDisposable对象上使用的用法,它说了一个有趣的词:

...使用块,在块结束后的某个时间自动调用Dispose方法.(它可能不是立即的;它取决于CLR.)

有趣的是" 它可能不是立即的;它取决于CLR ".任何人都可以提供更多细节吗?因为我们有一些奇怪的情况下,似乎在代码中使用(新MyDisposable()){...},块结束}后它不立即呼吁MyDisposable例如Dispose方法,但一段时间后.

更新:结论对我来说,在我看来,我在其他地方有问题.我认为可以在使用块结束后的某个时间调用Dispose方法.但是当它不是那样的时候,我必须在我的代码中的其他地方找到问题.谢谢你的回复!

Dar*_*rov 9

using (SomeDisposableResource resource = new SomeDisposableResource())
{
    // TODO: use the resource
}
Run Code Online (Sandbox Code Playgroud)

相当于:

SomeDisposableResource resource = new SomeDisposableResource();
try
{
    // TODO: use the resource
}
finally
{
    if (resource != null)
    {
        ((IDisposable)resource).Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,由你来得出结论.一切都取决于你如何立即定义.在多线程环境中,可以在try块和资源处理之间执行其他操作,但是当它被包装在finally块中时,可以保证将调用Dispose方法.


vcs*_*nes 6

我对这种说法持怀疑态度,并认为它们意味着其他东西(可能是垃圾收集).using语句只是try/finally块的语法糖,finally块调用dispose.鉴于此C#:

using (var fs = new FileStream("C:\\blah.txt", FileMode.CreateNew))
{
    fs.WriteByte(7);
}
Run Code Online (Sandbox Code Playgroud)

IL看起来像这样:

//snipped
L_000e: nop 
L_000f: ldstr "C:\\blah.txt"
L_0014: ldc.i4.1 
L_0015: newobj instance void [mscorlib]System.IO.FileStream::.ctor(string, valuetype [mscorlib]System.IO.FileMode)
L_001a: stloc.0 
L_001b: nop 
L_001c: ldloc.0 
L_001d: ldc.i4.7 
L_001e: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
L_0023: nop 
L_0024: nop 
L_0025: leave.s L_0037
L_0027: ldloc.0 
L_0028: ldnull 
L_0029: ceq 
L_002b: stloc.1 
L_002c: ldloc.1 
L_002d: brtrue.s L_0036
L_002f: ldloc.0 
L_0030: callvirt instance void [mscorlib]System.IDisposable::Dispose()
L_0035: nop 
L_0036: endfinally 
L_0037: nop 
L_0038: nop 
L_0039: ret 
.try L_001b to L_0027 finally handler L_0027 to L_0037
Run Code Online (Sandbox Code Playgroud)

注意最后一行它只是一个.try和.finally.这也在C#规范中有说明:http://msdn.microsoft.com/en-us/library/aa664736.aspx