看起来像其他人一样,我很晚才注意到你在powershell中。在这种情况下,这并不重要。 无论如何,当外壳结束时,一切都会被清理干净。我想你可以添加一个 [catch] 并且如果它仍然打开,可能会关闭/处理那里的连接,但我认为只有当你计划让你的脚本继续时才有必要这样做。
我将在下面留下我冗长的 c# 答案。尽管它并不真正适用于您的脚本,但它解释了差异(或缺乏差异)。
简短的回答(对于 c#):
using (var conn = new OracleConnection(connectionString))
{
}
“使用”确保 .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();
}
也就是说,对于一次性对象的推荐模式是使用“使用”块。是的,我想您确实可以选择使用 close 重新打开连接,但我认为这不是一件有用的事情。
如果您没有使用 using 或 finally 并且抛出异常并且永远不会调用 close/dispose,则释放与 db 的连接将是不确定的 - 只要垃圾收集器处理它,就会发生 Dispose(false) -在您用完与数据库的连接之后,这可能需要很长时间。
OracleConnection conn = null;
conn = new OracleConnection(connectionString);
conn.Open();
//exception occurs - Close is never called - resource leak!!
conn.Close();