SQL Server精简版4 - AccessViolationException(SQL Se

2019-09-20 20:53发布

我建设使用实体框架代码优先和SQL Server Compact 4.0 .NET 4 WPF应用程序。 我想打电话给DbContext.SaveChanges()在后台线程,以避免阻塞UI,但我偶尔会收到以下异常:

System.AccessViolationException occurred
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=System.Data.SqlServerCe
  StackTrace:
       at System.Data.SqlServerCe.NativeMethodsHelper.OpenStore(IntPtr pOpenInfo, IntPtr pfnOnFlushFailure, IntPtr& pStoreService, IntPtr& pStoreServer, IntPtr& pQpServices, IntPtr& pSeStore, IntPtr& pTx, IntPtr& pQpDatabase, IntPtr& pQpSession, IntPtr& pStoreEvents, IntPtr& pError)
       at System.Data.SqlServerCe.NativeMethods.OpenStore(IntPtr pOpenInfo, IntPtr pfnOnFlushFailure, IntPtr& pStoreService, IntPtr& pStoreServer, IntPtr& pQpServices, IntPtr& pSeStore, IntPtr& pTx, IntPtr& pQpDatabase, IntPtr& pQpSession, IntPtr& pStoreEvents, IntPtr& pError)
       at System.Data.SqlServerCe.SqlCeConnection.Open(Boolean silent)
       at System.Data.SqlServerCe.SqlCeConnection.Open()
       at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
       at System.Data.EntityClient.EntityConnection.Open()
       at System.Data.Objects.ObjectContext.EnsureConnection()
       at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
       at System.Data.Entity.Internal.InternalContext.SaveChanges()
       at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
       at System.Data.Entity.DbContext.SaveChanges()
       at SourceLog.Model.LogSubscriptionManager.<SaveChanges>b__2() in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\LogSubscriptionManager.cs:line 51
  InnerException: (null)

下面是调用代码SaveChanges()

internal static readonly object DbSaveLockObject = new object();
public static void SaveChanges()
{
    Task.Factory.StartNew(() =>
    {
        lock (DbSaveLockObject)
        {
            Debug.WriteLine(DateTime.Now + ": SaveChanges in lock");
            Db.SaveChanges();
        }
    });
}

Answer 1:

这里的问题不序列化访问的DbContext对象,它避免了访问来自不同的线程相同的对象。 所以,解决的办法是,以确保您创建一个新的DbContext对象每次需要与数据库进行交互的时间。

using (var db = new SourceLogContext())
{
    db.LogSubscriptions.First(s => s.LogSubscriptionId == LogSubscriptionId)
        .Log.Add((LogEntry)e.LogEntry);
    db.SaveChanges();
}

我不是很确定的是你如何处理更新UI。 如果上面的代码是在后台线程运行,并且UI之前已经绑定到LogSubscription.Log集合,然后在UI线程被引用集合的不同实例,你必须添加新条目到此集合为好。

_uiThread.Post(entry => Log.Add((LogEntry)entry), e.LogEntry);

更复杂的是延迟加载,其中的实体可能不会从数据库中加载,直到用户通过用户界面对其进行访问。 为了解决这个问题,似乎你必须保持至少一个参考的DbContext的UI线程的生命..

private static readonly SourceLogContext DbUILazyLoadContext = new SourceLogContext();

我希望能在这些问题上的意见..



Answer 2:

一个AccessViolationException只在可验证托管代码与非托管代码或不安全的托管代码交互出现。

你应该通过这个博客我对如何解决访问voilation MS 错误:http://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using- SQL服务器紧凑的数据库与- ADO净provider.aspx



文章来源: SQL Server Compact Edition 4 - AccessViolationException