他のみんなと同じように見えますが、あなたが 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();
}
そうは言っても、識別可能なオブジェクトの推奨されるパターンは、「使用中」ブロックを使用することです。はい、クローズで接続を再開するオプションがあるのは事実だと思いますが、それが有用なことだとは思いません。
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();