C# 并行遍历上下文
据我所知,并行使用C# 并行遍历上下文,c#,entity-framework,parallel-processing,task-parallel-library,C#,Entity Framework,Parallel Processing,Task Parallel Library,据我所知,并行使用DataContext不是线程安全的,但前提是您将上下文声明为static(基于MSDN文档) 这就是我所做的,一次我发现它有效,另一次它失败了 MSDN: 线程安全 “此类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。” 似乎我遇到了与DataContext相关的常见错误,这是线程安全性不足 在这里我解释一下我想做什么,以及我想要的结果是什么,希望在这个案例中得到专家的帮助和想法 我想对大约100000条记录进行大
DataContext
不是线程安全的,但前提是您将上下文声明为static
(基于MSDN文档)
这就是我所做的,一次我发现它有效,另一次它失败了
MSDN:
线程安全
“此类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。”
似乎我遇到了与DataContext
相关的常见错误,这是线程安全性不足
在这里我解释一下我想做什么,以及我想要的结果是什么,希望在这个案例中得到专家的帮助和想法
我想对大约100000条记录进行大量分析
错误是:
调用EntityMemberChanged或EntityComplexMemberChanged时,未首先调用具有相同属性名称的同一更改跟踪程序上的EntityMemberChanged或EntityComplexMemberChanged。有关正确报告更改的信息,请参阅实体框架文档
指向设计器代码中的此行:
ReportPropertyChanged("ProductName");
我的代码中有什么:
//On form Load
if (Repository.ContextP == null)
Repository.ContextP = new dbEntities();
private void btnProcess_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
Process(), TaskCreationOptions.LongRunning);
}
private void Process()
{
var query = from W in Repository.ContextP.Products
select W;
Parallel.ForEach(query, options , product =>
{
// There are some heavy processes to get stFormattedDef
product.ProductName= stFormattedDef;
}
}
// The Repository - static
static class Repository
{
public static dbEntities ContextP { get; set; }
}
安全性和数据上下文生命周期不应该是问题,因为分析处于构建阶段,并且是本地的
我做错了什么
有什么建议吗
类似情况下的想法或经验?我不知道EF,但从问题和评论来看,我认为问题在于您不能同时从不同的线程设置
ProductName
,即使它是针对不同的产品
(因为它们都使用相同的非线程安全DataContext
)
因此,我的建议是并行运行代价高昂的操作,但要确保每次仅从一个线程设置ProductName
。最简单的方法是使用锁
:
var productLock = new object();
Parallel.ForEach(query, options , product =>
{
// There are some heavy processes to get stFormattedDef
lock (productLock)
{
product.ProductName = stFormattedDef;
}
}
就像我说的,我不知道EF,所以我不完全理解这个问题。因此,这可能不是正确的解决方案。与静态DataContext相关的可能重复?一个开放的生活环境?(在应用程序生命周期内)?您是否错误地阅读了螺纹安全警告?实例成员不保证线程安全啊。。。明白了。对不起,我误读了你的问题所说的内容。@Sypress,但这不是警告所说的。它没有提到将数据上下文保存在哪里,这没有任何意义。据说,
DataContext
(如产品
)的实例成员从来都不是线程安全的。感谢svick+1在本例中分享您的想法,我认为锁定可能是一个选项,当我尝试另一个异常时,它再次与EF相关:“无法执行更新操作,因为适配器的连接未打开。“,我仍在使用它,以查看适合我需要的最佳解决方案。但问题将出现在事务期间保存上下文时前一个错误下方的某些行中,我认为错误可能来自我们选择的当前策略。谢谢,我正在尝试处理所有可能的替代方案,看看什么时候我能得到最好的结果。