帮我理解。我读过
“终结者的执行时间和顺序无法预测或预先确定”
正确的?
但是查看 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 之前完成,这可能会产生不良影响,也许 Ayende 围绕此添加了一个 catch all 子句?
实际上深入研究 Esent 代码,它不使用 SafeHandles。
根据 CLR 通过 C# 这很危险吗?
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 是否以正确的方式处理终结/处置,其次是 RavenDB 以正确的方式处理终结器还是补偿 Managed Esent?