看起来和其他人一样,我最近注意到你在 powershell 中。在这种情况下,这并不重要。无论如何,当外壳结束时,一切都会被清理干净。我想你可以添加一个 [catch] 并可能关闭/处置那里的连接(如果它仍然打开),但我认为只有当你计划让你的脚本继续时才有必要。
我将在下面留下我冗长的 C# 答案。尽管它并不真正适用于您的脚本,但它解释了差异(或缺乏差异)。
简短的答案(对于 c#):
using (var conn = new OracleConnection(connectionString))
{
}
“using”确保即使抛出异常,.Dispose也会在块的末尾被调用。这样,您就不会冒连接被孤立的风险,直到垃圾收集最终开始清理它,并且这可能在您用完数据库连接之后就可以了。
长答案:
使用反射器,您将看到 Dispose 调用 Close:
protected override void Dispose(bool disposing)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry);
this.m_disposed = true;
this.m_dataSource = string.Empty;
this.m_serverVersion = string.Empty;
try
{
bool flag = this.m_connectionState == ConnectionState.Closed && this.m_oracleConnectionImpl == null;
try
{
if (!disposing)
{
if (!flag)
{
if (OraclePool.m_bPerfNumberOfReclaimedConnections)
OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfReclaimedConnections, this.m_oracleConnectionImpl, this.m_oracleConnectionImpl.m_cp);
}
}
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
if (!flag)
{
try
{
this.Close();
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
}
try
{
base.Dispose(disposing);
}
catch (Exception ex)
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
try
{
GC.SuppressFinalize((object) this);
}
catch (Exception ex)
{
if (!ProviderConfig.m_bTraceLevelPublic)
return;
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
}
catch (Exception ex)
{
if (!ProviderConfig.m_bTraceLevelPublic)
return;
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Error, ex.ToString());
}
finally
{
if (ProviderConfig.m_bTraceLevelPublic)
Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit);
}
}
有什么真正的区别吗?否 - 非托管资源是使用 .Close 处理的连接。如果您在finally 块中检查连接状态并在连接仍处于打开状态时调用.Close,那么您不会发现任何功能差异(除了延迟跟踪)。
OracleConnection conn = null;
try
{
conn = new OracleConnection(connectionString);
}
finally
{
if(conn.State != ConnectionState.Closed)
conn.Close();
}
也就是说,对于不可处理对象的推荐模式是使用“using”块。是的,我认为您确实可以选择通过关闭重新打开连接,但我认为这不是一件有用的事情。
如果您没有使用 using 或 finally 并且抛出异常并且从未调用 close/dispose,则释放与数据库的连接将是不确定的 - 每当垃圾收集器处理它时就会发生 Dispose(false) -这可能是在您耗尽与数据库的连接之后很长一段时间。
OracleConnection conn = null;
conn = new OracleConnection(connectionString);
conn.Open();
//exception occurs - Close is never called - resource leak!!
conn.Close();