在使用“using”块时,有哪些特定情况应该(或不应该)使用:
using(SomeType t = new SomeType()){
...
}
using( Log log = new Log("Doing stuff") )
{
// Stuff
}
可以将log类的构造函数修改为输出消息,同时Dispose方法也要输出消息。实现finalizer(~Log),如果没有调用Dispose方法则会断言以确保“using”记住了“new Log”。
当SomeType
类实现IDisposable
时。
IDisposable
接口的类型,是否存在不应使用 using
模式的情况? - Matthewusing
与任何异步操作关联时,你需要谨慎行事:http://softwareblog.alcedo.com/post/2011/12/09/Using-blocks-and-asynchronous-operations.aspx - Benjol如果类型实现了IDisposable
,则使用using
,除非你打算无论如何都要用try
/catch
块来包装它,那么你也可以(根据你喜欢的外观)使用finally
块。
我看到许多其他答案表明当你应该使用using
语句时。我想解决的是,什么情况下不应该使用using
语句:
如果你需要在当前函数的范围之外使用对象,则不要使用using
块。好的例子是返回数据库连接的工厂方法或需要返回数据读取器的方法。在这两种情况下,如果你使用using
语句创建对象,则它将在方法返回之前被处理,因此无法在方法外使用。
现在,你仍然希望确保这些对象被处理,因此你可能仍然需要在某个地方使用using
语句。只是不要把它包含在实际创建对象的方法中。相反,可以在函数调用本身中包装一个using
语句。
例子:
using(SqlConnection MyConnection = new SqlConnection("Connection string"))
{
MyConnection.Open();
//...
// 1. SQLConnection is a type that implements IDisposable
// 2. So you can use MyConnection in a using statement
// 3. When using block finishes, it calls Dispose method of
// SqlConnection class
// 4. In this case, it will probably close the connection to
// the database and dispose MyConnection object
}
您可以创建自己的对象来实现IDisposable:
public class MyOwnObjectThatImplementsIDisposable : IDisposable
{
//... some code
public void Dispose()
{
// Put here the code you want to be executed when the
// using statement finish.
}
}
因此,您可以在using语句中使用一个MyOwnObjectThanImplementsIDisposable类型的对象:
using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
{
// When the statement finishes, it calls the
// code you´ve writed in Dispose method
// of MyOwnObjectThatImplementsIDisposable class
}
当SomeType实现IDisposable接口时。
这提示开发人员SomeType使用需要清理的非托管资源。
如果您需要一个总结规则,那么在使用IDisposable的对象且没有catch语句时,请使用using。实际上,using是这种模式:
try
{
//instantiate and use object
}
finally
{
//dispose object
}
如果您不需要捕获异常,使用try/except可以减少输入,这是一件好事。
using
语句对于实现IDisposable接口的类型非常方便。当代码块退出using
语句的作用域时,Dispose()
会被隐式调用。在使用后立即释放对象时,这是一个好习惯。在使用using
块时需要特别小心的一种情况是使用WCF服务客户端。
正如MSDN文章中所述,将WCF客户端(实现了IDisposable
)包装在using
块中可能会掩盖任何导致客户端处于故障状态的错误(例如超时或通信问题)。简而言之,当调用Dispose()
时,客户端的Close()
方法会触发,但由于它处于故障状态,会抛出错误。原始异常随后被第二个异常掩盖。这不好。
有各种解决方法,包括MSDN文章本身提供的方法。其他方法可以在IServiceOriented和blog.davidbarret.net上找到。
我自己更喜欢最后一种方法。
该接口提供了Dispose方法,它应该释放对象的资源。如果不调用此方法,则对象将一直停留在内存中,直到CLR想要执行垃圾回收为止。如果程序员使用USING语句,则在结束时对象将被处理,并且所有资源将被释放。
非常重要的是,所有不再使用的资源尽快释放。
有关更多信息,请访问以下链接:microsoft