簡體   English   中英

SQL Server Compact Edition 4 - AccessViolationException

[英]SQL Server Compact Edition 4 - AccessViolationException

我正在使用Entity Framework代碼和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();
        }
    });
}

這里的問題不是序列化對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);

進一步的復雜是延遲加載,其中實體可能無法從數據庫加載,直到用戶通過UI訪問它們。 為了處理這個問題,你似乎必須在UI線程的生命周期中至少保留一個對DbContext的引用。

private static readonly SourceLogContext DbUILazyLoadContext = new SourceLogContext();

我歡迎就這些問題發表評論。

僅當可驗證的托管代碼與非托管代碼或不安全的托管代碼交互時,才會發生AccessViolationException。

你應該通過這個博客我的MS如何解決訪問voilation 錯誤:http://blogs.msdn.com/b/sqlservercompact/archive/2009/05/06/troubleshooting-access-violation-exception-while-using- SQL服務器緊湊的數據庫與- ADO凈provider.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM