我们在设计多线程实体框架驱动的应用程序时遇到一些麻烦,并希望得到一些指导.我们在不同的线程上创建实体,将实体添加到集合中,然后将数据绑定到各种wpf控件.ObjectContext类不是线程安全的,所以管理它我们基本上有两个解决方案:
解决方案1具有单个上下文并小心使用锁定以确保没有2个线程同时访问它.这实现起来相对简单,但要求上下文在应用程序期间保持活动状态.像这样打开一个上下文实例是不是一个坏主意?
解决方案2是按需创建上下文对象,然后立即分离对象,然后将它们保存在我们自己的集合中,然后重新附加它们以进行任何更新.但是这有一些严重的问题,因为当分离对象时,它们会丢失对导航属性对象的引用.还有一个问题是,2个线程仍然可以尝试访问单个对象,并且都尝试将()附加到上下文.此外,每次我们想要访问实体导航属性时,我们都需要提供新的上下文.
问:两种解决方案中的任何一种都有效,如果不是,您如何建议我们解决这个问题?
我正在使用Parallel.ForEach它,它极大地提高了我的代码的性能,但我对DbContext多线程感到好奇。我知道它不是线程安全的,所以我在需要的地方使用锁。
循环遍历字典并计算统计信息:
Dictionary<string, List<decimal>> decimalStats = new Dictionary<string, List<decimal>>(); // this gets populated in another irrelevant loop
List<ComparativeStatistic> comparativeStats = db.ComparativeStatistics.ToList();
var statLock = new object();
Parallel.ForEach(decimalStats, entry =>
{
List<decimal> vals = ((List<decimal>)entry.Value).ToList();
if (vals.Count > 0)
{
string[] ids = entry.Key.Split('#');
int questionId = int.Parse(ids[0]);
int yearId = int.Parse(ids[1]);
int adjacentYearId = int.Parse(ids[2]);
var stat = comparativeStats.Where(l => l.QuestionID == questionId && l.YearID == yearId && l.AdjacentYearID == adjacentYearId).FirstOrDefault();
if (stat == null)
{ …Run Code Online (Sandbox Code Playgroud) c# parallel-processing multithreading entity-framework parallel.foreach