C# SqlCeConnection dispose中的访问冲突异常

C# SqlCeConnection dispose中的访问冲突异常,c#,.net,dll,sql-server-ce,access-violation,C#,.net,Dll,Sql Server Ce,Access Violation,应用程序/代码说明: 我的应用程序基于c#,并使用SQL Server CE和iv'e在同一代码位置仅两次出现此异常。直到这个版本,这个例外的崩溃才被引入。此版本中唯一的更改是将.net framework更改为4.5.2 我在处置SqlCeConnection时遇到访问冲突异常,错误如下: 试图读取或写入受保护的内存。这通常是一个问题 表示其他内存已损坏 此异常未被.net的try-catch子句拦截-它会导致崩溃 在我的代码中,我使用以下命令来运行 try { var connect

应用程序/代码说明:

我的应用程序基于c#,并使用SQL Server CE和iv'e在同一代码位置仅两次出现此异常。直到这个版本,这个例外的崩溃才被引入。此版本中唯一的更改是将.net framework更改为4.5.2

我在处置
SqlCeConnection
时遇到访问冲突异常,错误如下:

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

此异常未被.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 
<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 
ntdll!NtWaitForMultipleObjects+a
内核库!WaitForMultipleObjectsEx+e8
内核32!WaitForMultipleObjectsExImplementation+b3
内核32!WerpertFaultInternal+215
内核32!WerpertFault+77
内核32!BasepReportFault+1f
内核32!未处理的异常过滤器+1fc
ntdll!??:::FNODOBFM::`string'+2335
ntdll_C_特定的_处理程序+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(布尔)+f1
系统!!System.ComponentModel.Component.Dispose()+1b
我在互联网上找到了一些建议解决方案的参考资料:

  • 可能的解决方案:检查同一连接上的多线程问题()

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

  • 可能的解决方案:sql ce版本不匹配()

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

  • 可能的解决方案有以下问题:

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

  • 我考虑的最后一件事可能是DLL的卸载问题(请看第二个调用堆栈)。我的猜测是,dll是从应用程序中卸载的,而应用程序需要它们来执行dispose操作,但它有点模糊,而且是一个“长镜头”


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

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

    从第二个调用堆栈中,我可以看到卸载了本机DLL,我猜SQL连接的dispose方法使用的是它当前释放的方法之一。 我通过进程转储验证了所有SqlCeConnection类型都处于dispose过程中

    看到ErikEj的评论让我意识到,如果我能看看SQL-CE3.5到4.0(System.Data.SqlServerCe.dll)之间的代码差异,那就更好了

    查看代码后,我可以看到发布的方法被移动到dispose方法中的稍后位置

    此外,我可以看到,在调用SafeRelease之前,还有一个检查,检查安全发布所需的本机DLL是否已经发布,并引发异常

    总之,SQL-CE4.0针对同一问题有两种解决方案

    我的猜测是,这个问题是因为这个

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


    更好的解决方案是转到SQL-CE4.0。

    您是否尝试共享您的SQL-CEDB?例如,多个用户(进程)访问共享位置上的数据库?我会尝试将其报告给M$connect-connect.microsoft.com.C Sharper-不,数据库不是跨进程共享的,只有应用程序进程正在访问它。为什么要将“SELECT*”与ExecuteScalar结合使用?请选择单个值。我会尝试最新的SQL CE 3.5 SP2版本-您无法捕获
    AccessViolationException
    或任何其他损坏状态异常。这是严重错误的迹象,内存已经损坏。有关解决方法,请参阅。(该变通方法应仅用于调试,而不用于生产代码。)