在C#中对同一作用域使用多个using语句时,是否保证调用Dispose()方法的顺序?
换句话说,是否保证先调用stf2的Dispose()方法,然后再调用stf1的Dispose()方法?(基本上:Dispose()方法的调用顺序与它们所属对象的分配顺序相反?由于可能的重新排序,因此无法保证。Dispose在结束卷曲(或示例中的隐式卷曲)上调用。在非优化调试版本中,您将始终看到预期的顺序。你可以用它来强制执行操作顺序在C#中对同一作用域使用多个using语句时,是否保证调用Dispose()方法的顺序?,c#,using,unmanagedresources,destruction,C#,Using,Unmanagedresources,Destruction,换句话说,是否保证先调用stf2的Dispose()方法,然后再调用stf1的Dispose()方法?(基本上:Dispose()方法的调用顺序与它们所属对象的分配顺序相反?由于可能的重新排序,因此无法保证。Dispose在结束卷曲(或示例中的隐式卷曲)上调用。在非优化调试版本中,您将始终看到预期的顺序。你可以用它来强制执行操作顺序 using (Stuff1 stf1 = new Stuff1(...)) // Allocation of stf1 using (Stuff2 stf2 = n
using (Stuff1 stf1 = new Stuff1(...)) // Allocation of stf1
using (Stuff2 stf2 = new Stuff2(...)) // Allocation of stf2
{
try
{
// ... do stuff with stf1 and stf2 here ...
}
catch (Stuff1Exception ex1)
{
// ...
}
catch (Stuff2Exception ex2)
{
// ...
}
} // Automatic deterministic destruction through Dispose() for stf1/stf2 - but in which order?
发布模式优化是以这样一种方式进行的,即在所有指令完成后,保证在该线程上获得可预测的结果。其他一切(从单独核心上的不同线程查看)都可以获得。从另一个线程观察到,stf2尚未被释放,但stf1已被释放,这并不违反规则。除非你强制执行命令。尝试写入一些断言并在下运行,因为Stuff1位于内部块中,所以Stuff2将在Stuff1之前进行处理
即使您没有在Stuff1的外部块上使用大括号,它仍然与您使用的一样。使用语句与其他块级语句没有什么不同。如果您编写了如下代码:
using (Stuff1 stf1 = new Stuff1(...)) // Allocation of stf1
using (Stuff2 stf2 = new Stuff2(...)) // Allocation of stf2
{ {
try
{
// ... do stuff with stf1 and stf2 here ...
}
catch (Stuff1Exception ex1)
{
// ...
}
catch (Stuff2Exception ex2)
{
// ...
}
} Thread.MemoryBarrier(); }
你会很清楚事情发生的顺序(不是我会推荐那种特定的结构),因为它与下面的完全相同:
if (...)
if (...)
{
}
使用的也是如此。您的代码与以下代码相同:
if (...)
{
if(...)
{
}
}
在这里,很明显,内部using块首先终止,因此应该首先释放它的资源。是的,先调用stf2.Dispose,然后再调用stf1.Disposeusing语句被转换为try finally。这只是语法上的糖分。。因此,您的示例在编译时被翻译为以下内容是正确的:
using (...)
{
using(...)
{
}
}
是的,在使用范围结束时调用DISSION方法,因此,处理对象()方法被调用的对象的分配顺序为“< /P>”,因为我来自C++世界,我很好奇。在什么情况下会发生这种“重新排序”?Dispose被确定性地调用,并且那里有一个隐式代码块,意味着#2将在#1OK之前退出它的块。我认为Dispose的调用顺序只在单线程模式下得到保证。很高兴知道。我来自C++世界,想尝试一些模式,避免我需要为所有对象写显式的处理()调用。与析构函数类似,对于某些状态机中的RAII,可以反转先前在构造函数中完成的某些状态设置。谢谢using语句有点神奇,但这种解释使其行为清晰明了。谢谢
try
{
Stuff1 stf1 = new Stuff1());
try
{
Stuff2 stf2 = new Stuff2();
}
finally
{
stf2.Dispose();
}
}
finally
{
stf1.Dispose();
}