SqlCeConnection 处理中的访问冲突异常 [英] Access Violation Exception in SqlCeConnection dispose

查看:29
本文介绍了SqlCeConnection 处理中的访问冲突异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序/代码说明:

我的应用程序基于 c# 并使用 SQL Server CE,并且我在同一代码位置仅遇到两次此异常.直到此版本才引入此异常的崩溃.此版本中唯一的变化是将 .net 框架更改为 4.5.2.

My application is based on c# and uses SQL Server CE and iv'e got this exception only twice at the same code location. the crash with this exception was not introduced till this version. the only change in this version was changing the .net framework to 4.5.2.

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

I'm getting access violation exception on the dispose of an SqlCeConnection with the following error:

试图读取或写入受保护的内存.这通常是一个指示其他内存已损坏.

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

.net 的 try catch 子句不会拦截此异常 - 它会导致崩溃.

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

In my code I use the following to run

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);
}

第一次崩溃的调用堆栈:

call stack for the first crash:

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 

第二次崩溃的调用堆栈:

call stack for the second crash:

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 
<Unloaded_sqlcese35.dll>+7c88c 
<Unloaded_sqlceqp35.dll>+102790 
0x06ccc898 
0x06f9efc8 
0x1eca8018 
0x1f207400 
<Unloaded_sqlcese35.dll>+228dc 
0x00000004 
0x2edff008 
0x00000002 
0x00000003 
0x00000004 
<Unloaded_sqlcese35.dll>+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 

我在互联网上找到了一些参考资料,提出了一些解决方案:

I found some references on the internet that suggests some solutions:

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

  1. Probable solution: check multithreading issue on the same connection (attempted to read write protected memory. this is often an indication that other memory is corrupt)

拒绝:
一种.连接是在 using 方括号中创建的,不会被重用.
湾调用方法每 5 分钟调用一次,并通过转储文件验证它不是同时调用的.

Rejection:
a. the connection is created in the using brackets and doesn't get reused.
b. the calling method is called every 5 minutes and verified via the dump file that it was not called simultaneously.

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

Probable solution: sql ce version mismatch (http://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.dll, System.Data.SqlServerCe.dll DLL 的版本为 3.05.8080.0

Probable Rejection: I can see in the version installed is 3.5 SP2 (3.5.8080.0) and from the modules located in the dump I can see the sqlceme35.dll, System.Data.SqlServerCe.dll DLL's are with version 3.05.8080.0

可能的解决方案有问题如下:https://stackoverflow.com/a/20492181/1447518

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

Probable Rejection: it doesn't sound right from a statistical perspective- the code crashed twice in the same place although there another place in the application code which writes and read to a different DB and the application didn't crash there.

我想到的最后一件事可能是 DLL 的卸载问题(看看第二个调用堆栈).我的猜测是 dll 是从应用程序中卸载的,而应用程序需要它们来进行处理,但它的接缝有点模糊和远景"

The last thing I was thinking about, may suggest a unload problem of DLLs (take a look at the second call stack). My guess is that the dll's are unloaded from the application while the application needed them in order to do a dispose, but it seams a bit blurry and a 'long shot'

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

My question is: what may cause the problem, and what is a probable solution?

推荐答案

虽然这个方案还没有验证,但是解决方案如下:

Although this solution is not yet verified, the solution is as follows:

从第二个调用堆栈中我可以看到卸载了本机 DLL,我的猜测是 SQL 连接的 dispose 方法正在使用它当前处置的方法之一.我彻底验证了所有 SqlCeConnection 类型都在处理过程中的进程转储.

From the second call stack i can see there is unload of native DLL's, my guess was that the dispose method of the SQL connection was using one of the methods it currently disposed. I verified thorough the Process dump that all the SqlCeConnection types were in the process of dispose.

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

Seeing ErikEj comment made me realize it's will be better if i will take a look in the code differences that was made between SQL-CE 3.5 to 4.0 (System.Data.SqlServerCe.dll).

查看代码后,可以看到release的方法被移到了dispose方法里面的后面的位置.

after viewing the code, i could see that the method of the release was moved to a later position inside the dispose method.

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

In addition i could see that before calling SafeRelease there was another check that checks if the native DLLs that were needed for safe release was released already- and throw an exception.

最重要的是,SQL-CE 4.0 针对同一问题有 2 个解决方案.

bottom line, SQL-CE 4.0 has 2 solutions for the same issue.

我的猜测是这个问题是由这个引起的.

my guess is that this issue was caused because of this.

目前的解决方案是在整个应用程序生命周期内保持连接(没有连接字符串),这会导致指针池在整个应用程序生命周期内将本机 Dll 保留在内存中.

the solution for now was to keep a connection during all the application life-cycle (which has no connection string), this cause the pointer pool to keep the native Dlls in the memory for all the application life-cycle.

更好的解决方案是迁移到 SQL-CE 4.0.

the better solution is to move to SQL-CE 4.0 .

这篇关于SqlCeConnection 处理中的访问冲突异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆