在 C# 中创建一个 IDisposable 类,该类在完成后清理 SqlConnection
在回答上一个问题时,有人建议:
将 SqlConnection 作为类的成员变量,但使类 IDisposable 并在释放该类时释放 SqlConnection
我已经整理了此建议的实现(如下),但想检查此实现是否正确(显然它不正确)目前除了打开连接之外没有做任何事情,但想法是其中会有一些方法可以使用该连接并且能够依赖它的存在和打开)。
public class DatabaseRecord : IDisposable
{
protected SqlConnection connection;
public DatabaseRecord()
{
connection = new SqlConnection("ConnectionString");
connection.Open();
}
// IDisposable implementation
private bool disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
connection.Dispose();
}
disposed = true;
}
}
// Destructor
~DatabaseRecord()
{
Dispose(false);
}
}
这行得通吗?使用 DatabaseRecord 实例的类是否需要执行任何特殊操作,或者一旦不再使用/引用实例,是否会自动调用 Dispose?这是否比在需要连接的每个单独方法主体中使用 using (var connection = new SqlConnection("...")) { }
更有效/更好?
In an answer to a previous question somebody recommended:
have the SqlConnection a member variable of your class, but make the class IDisposable and dispose of the SqlConnection when the class is disposed
I have put together an implementation of this suggestion (below) but wanted to check that this implementation is correct (obviously it doesn't currently do anything except open the connection but the idea is that there would be methods in there which would use the connection and which would be able to rely on it existing and being open).
public class DatabaseRecord : IDisposable
{
protected SqlConnection connection;
public DatabaseRecord()
{
connection = new SqlConnection("ConnectionString");
connection.Open();
}
// IDisposable implementation
private bool disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
connection.Dispose();
}
disposed = true;
}
}
// Destructor
~DatabaseRecord()
{
Dispose(false);
}
}
Will this work? Will classes which use instances of DatabaseRecord need to do anything special or will the Dispose automatically be called once the instances are no longer used/ referenced? Is this more efficient/ better than using using (var connection = new SqlConnection("...")) { }
in each separate method body where the connection is needed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
SqlConnection 是托管资源,应在
if(处置)
块内处置。使用您的类的类应该处置它,最好使用using
块。这是否比 SqlConnections 的单独using
块更好将取决于此类的其他方法以及它们的使用方式。SqlConnection is a managed resource, and should be disposed within the
if (disposing)
block. Classes using your class should dispose it, ideally witrh ausing
block. Whether this is better than individualusing
blocks for SqlConnections will depend on the other methods of this class and how they are used.我看到的所有建议都说 DbConnection 应该保留最短时间,因此我希望在正在审查的代码中看到的格式是
All the advice I've seen says that
DbConnection
s should be kept around for the minimum time, so the format I'd prefer to see in code I'm reviewing isconnection.Dispose()
应移至if (disusing) { ... }
块。不需要调用Close()
,因为Dispose()
将在连接打开时关闭连接。connection.Dispose()
should be moved toif (disposing) { ... }
block. The calling ofClose()
is not required becauseDispose()
will close the connection when connection is open.这将会起作用,并且比多个 using 语句更有效。使用 DatabaseRecord 类的代码可以在 using 语句中执行此操作,以便在离开循环时自动清除该语句。
不过,一项建议是在 Dispose 方法中检查 Connection 对象的状态,如果在调用 dispose 之前仍处于打开状态,则将其关闭。
This will work and it will be more efficient that multiple using statements. The code that uses the DatabaseRecord class can do so inside a using statement to have it automatically cleaned up there when it leaves the loop.
One recommendation however, would be in the Dispose method to check the state of the Connection object and close it if it is still open before calling dispose.