5

İlk Varlık Framework kodu ve SQL Server Compact 4.0 kullanarak bir .NET 4 WPF uygulama inşa ediyorum. Ben UI engelleme önlemek için bir arka plan iş parçacığı üzerinde DbContext.SaveChanges() aramaya çalışıyorum ama bazen şu istisna alıyorum:SQL Server Compact Edition 4 - AccessViolationException

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

cevap

2

burada mesele, farklı parçacıkları aynı nesneye erişim kaçıyor DBContext nesneye erişimi seri hale değil nasıl giderileceği benim MS blog geçmesi gerektiğini

. Bu nedenle, çözüm her zaman veritabanında etkileşimde bulunmanız için yeni bir DbContext nesnesi oluşturmanızı sağlamaktır.

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

Tam olarak emin olmadığım şey, kullanıcı arabirimini güncellemeyle nasıl başa çıkacağınızdır. Yukarıdaki kod bir arka plan iş parçacığında çalışıyorsa ve kullanıcı arabirimi önceden LogSubscription.Log koleksiyonuna bağlanmışsa, UI iş parçacığı koleksiyonun farklı bir örneğini başvuruyor ve bu girdiye yeni girişi de eklemelisiniz.

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

bir başka komplikasyon kullanıcı UI üzerinden erişebilecek sahiptir dek kişiler veritabanından yüklenen olmayabilir geç yükleme olduğunu. Ben bu noktalara yorumlarınızı bekliyoruz ediyorum .. Eğer UI iş parçacığı ömrü boyunca DBContext için en az bir referans sürdürmek zorunda görünüyor

private static readonly SourceLogContext DbUILazyLoadContext = new SourceLogContext(); 

bu işlemek için ..

+2

Sorunu hiç çözdünüz mü? Benzer bir problemim var. –

+0

Gerçekten cevabımda sahip olduğumdan daha iyi bir anlayışa sahip değildim. Öğe bağlamına kez [AddNewLogEntry] (https://github.com/tomhunter-gh/SourceLog/blob/aed3718af18fcff471f04c83f83a0160b97b6829/SourceLog.Model/LogSubscription.cs#L90) yönteminde iki koleksiyonlarına eklenen görebilirsiniz koleksiyon ve bir kez "UI koleksiyonu". –

+0

Aynı problemi yaşadım, diğer süreçler onu kullanırken içeriğe erişmeye çalışan bir arka plan çalışması yapıyordu. Diğer işlemler bittikten ve çözdüğümden sonra bu aramayı değiştirdim. Sanırım onları sıralamak da işe yarayacaktı. EF'in iş parçacığını yönetmesini bildiğim kadarıyla, arka plan çağrısını yapana kadar böyle bir sorunum olmadı. – Hannish

0

Bir AccessViolationException: Burada

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() çağıran kod yalnızca doğrulanabilir yönetilen kodun yönetilmeyen kodla veya güvensiz yönetilen kodla etkileşmesi durumunda gerçekleşir. Bu erişim voilation error: 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

+0

Teşekkür nasıl yaptığınızı Bu makaleyi oku. Ben SQL CE 4.0 kullanıyorum ve makale olarak "uygulama bu nesnelere erişim serileştirmelidir" 'SaveChanges()' çağrıları serileştirmek için '' lock'' kullanmıştım .. –

+0

(ama yine de hata alıyorum. .) –