理解するのを手伝ってください。私はそれを読みました
「ファイナライザーの実行の時間と順序を予測または事前に決定することはできません」
正しい?
ただし、RavenDB ソース コード TransactionStorage.cs を見ると、これがわかります
~TransactionalStorage()
{
try
{
Trace.WriteLine(
"Disposing esent resources from finalizer! You should call TransactionalStorage.Dispose() instead!");
Api.JetTerm2(instance, TermGrbit.Abrupt);
}
catch (Exception exception)
{
try
{
Trace.WriteLine("Failed to dispose esent instance from finalizer because: " + exception);
}
catch
{
}
}
}
おそらく SafeHandle を使用してネイティブ リソースのハンドルを取得する API クラス (Managed Esent に属する)?
したがって、ネイティブ ハンドルの SafeHandle が TransactionStorage の前にファイナライズされる可能性があることを正しく理解していれば、望ましくない影響を与える可能性があります。
実際に Esent コードに飛び込むと、SafeHandles は使用されません。
C#経由のCLRによると、これは危険ですか?
internal static class SomeType {
[DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]
// This prototype is not robust
private static extern IntPtr CreateEventBad(
IntPtr pSecurityAttributes, Boolean manualReset, Boolean initialState, String name);
// This prototype is robust
[DllImport("Kernel32", CharSet=CharSet.Unicode, EntryPoint="CreateEvent")]
private static extern SafeWaitHandle CreateEventGood(
IntPtr pSecurityAttributes, Boolean manualReset, Boolean initialState, String name)
public static void SomeMethod() {
IntPtr handle = CreateEventBad(IntPtr.Zero, false, false, null);
SafeWaitHandle swh = CreateEventGood(IntPtr.Zero, false, false, null);
}
}
Managed Esent (NativeMEthods.cs) は次のようになります (Ints と IntPtrs を使用しますか?):
[DllImport(EsentDll, CharSet = EsentCharSet, ExactSpelling = true)]
public static extern int JetCreateDatabase(IntPtr sesid, string szFilename, string szConnect, out uint dbid, uint grbit);
Managed Esent はファイナライズ/破棄を正しい方法で処理していますか? 2 つ目は、RavenDB がファイナライザーを正しい方法で処理しているか、Managed Esent を補っていますか?