Csharp/C#教程:SqlCeConnection中的访问冲突exception处理分享


SqlCeConnection中的访问冲突exception处理

申请/代码说明:

我的应用程序基于c#并使用SQL Server CE,并且我在同一代码位置只获得此exception两次。 在此版本之前没有引入此exception的崩溃。 此版本中唯一的变化是将.net框架更改为4.5.2。

我在处理SqlCeConnection时遇到访问冲突exception,并出现以下错误:

尝试读取或写入受保护的内存。 这通常表明其他内存已损坏。

此exception不会被.net的try catch子句拦截 – 它会导致崩溃。

在我的代码中,我使用以下命令运行

 try { var connectionString = string.Format("{0}{1}{2}", "Data Source=", _localDB, ";File Mode=Read Write;Max Database Size=4000;Persist Security Info=False;"); using (var sqlCeConnection = new SqlCeConnection(connectionString)) { using (var sqlCeCommand = new SqlCeCommand()) { sqlCeCommand.Connection = sqlCeConnection; sqlCeCommand.CommandText = "SELECT * FROM Application"; sqlCeConnection.Open(); var result = (string)sqlCeCommand.ExecuteScalar(); isValid = !IsValid(result); } } } catch (Exception ex) { _log.Error("exception", ex); } 

第一次崩溃的调用堆栈:

 ntdll!ZwWaitForMultipleObjects+a KERNELBASE!WaitForMultipleObjectsEx+e8 kernel32!WaitForMultipleObjectsExImplementation+b3 kernel32!WerpReportFaultInternal+215 kernel32!WerpReportFault+77 kernel32!BasepReportFault+1f kernel32!UnhandledExceptionFilter+1fc ntdll! ?? ::FNODOBFM::`string'+2365 ntdll!_C_specific_handler+8c ntdll!RtlpExecuteHandlerForException+d ntdll!RtlDispatchException+45a ntdll!KiUserExceptionDispatcher+2e sqlcese35!__SafeRelease+c sqlcese35!Column::`vector deleting destructor'+5c sqlcese35!Object::DeleteObjects+39 sqlcese35!Table::`vector deleting destructor'+45 sqlcese35!Table::Release+27 sqlcese35!HashTable::~HashTable+2a sqlcese35!Store::~Store+12b sqlcese35!Store::Release+2a sqlceme35!ME_SafeRelease+17 DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr ByRef)+78 [[InlinedCallFrame] (System.Data.SqlServerCe.NativeMethods.SafeRelease)] System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef) System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+147 System.Data.SqlServerCe.SqlCeConnection.Dispose(Boolean)+f1 System_ni!System.ComponentModel.Component.Dispose()+18 

第二次崩溃的调用堆栈:

 ntdll!NtWaitForMultipleObjects+a KERNELBASE!WaitForMultipleObjectsEx+e8 kernel32!WaitForMultipleObjectsExImplementation+b3 kernel32!WerpReportFaultInternal+215 kernel32!WerpReportFault+77 kernel32!BasepReportFault+1f kernel32!UnhandledExceptionFilter+1fc ntdll! ?? ::FNODOBFM::`string'+2335 ntdll!_C_specific_handler+8c ntdll!RtlpExecuteHandlerForException+d ntdll!RtlDispatchException+45a ntdll!KiUserExceptionDispatcher+2e +7c88c +102790 0x06ccc898 0x06f9efc8 0x1eca8018 0x1f207400 +228dc 0x00000004 0x2edff008 0x00000002 0x00000003 0x00000004 +3fbd9 0x06ccc898 DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr ByRef)+78 [[InlinedCallFrame] (System.Data.SqlServerCe.NativeMethods.SafeRelease)] System.Data.SqlServerCe.NativeMethods.SafeRelease(IntPtrByRef) System.Data.SqlServerCe.SqlCeConnection.ReleaseNativeInterfaces()+147 System.Data.SqlServerCe.SqlCeConnection.Dispose(Boolean)+f1 System_ni!System.ComponentModel.Component.Dispose()+1b 

我在互联网上找到了一些建议,提出了一些解决方案:

  1. 可能的解决方案:检查同一连接上的multithreading问题( 尝试读取写保护的内存。这通常表明其他内存已损坏 )

    拒绝
    一个。 连接是在使用括号中创建的,不会被重用。
    湾 调用方法每5分钟调用一次,并通过转储文件validation它没有被同时调用。

  2. 可能的解决方案: sql ce版本不匹配( https://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using-sql-server-compact-database- with-ado-net-provider.aspx )

    可能的拒绝 :我在安装的版本中看到的是3.5 SP2(3.5.8080.0),从转储中的模块我可以看到sqlceme35.dllSystem.Data.SqlServerCe.dll DLL的版本是3.05.8080.0

  3. 可能的解决方案有以下几点: https : //stackoverflow.com/a/20492181/1447518

    可能的拒绝 :从统计角度来看听起来不对 – 代码在同一个地方崩溃了两次,尽管在应用程序代码中有另一个地方写入和读取到不同的数据库并且应用程序没有在那里崩溃。

  4. 我想到的最后一件事,可能会建议DLL的卸载问题(看看第二个调用堆栈)。 我的猜测是dll是从应用程序中卸载的,而应用程序需要它们才能进行处理,但它接缝有点模糊和“长镜头”

我的问题是:什么可能导致问题,什么是可能的解决方案?

虽然此解决方案尚未validation,但解决方案如下:

从第二个调用堆栈我可以看到卸载本机DLL,我的猜测是SQL连接的dispose方法正在使用它当前处理的方法之一。 我通过Process dumpvalidation了所有SqlCeConnection类型都在处理过程中。

看到ErikEj的评论让我意识到如果我看一下SQL-CE 3.5到4.0之间的代码差异(System.Data.SqlServerCe.dll)会更好。

在查看代码之后,我可以看到释放的方法被移动到dispose方法中的稍后位置。

此外,我可以看到,在调用SafeRelease之前,还有另一个检查,检查安全释放所需的本机DLL是否已经释放 – 并抛出exception。

最重要的是,SQL-CE 4.0针对同一问题提供了2个解决方案。

我的猜测是这个问题是由于这个原因引起的。

现在的解决方案是在所有应用程序生命周期(没有连接字符串)期间保持连接,这会导致指针池将本机Dll保留在内存中以用于所有应用程序生命周期。

更好的解决方案是转向SQL-CE 4.0。

上述就是C#学习教程:SqlCeConnection中的访问冲突exception处理分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1031272.html

(0)
上一篇 2022年1月13日
下一篇 2022年1月13日

精彩推荐