据我所知,在并行中使用DataContext
不是线程安全的,但前提是您将上下文声明为static
(基于MSDN文档)
这就是我所做的,一旦我发现它有效,另一次失败了!
MSDN: 线程安全 “此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。任何实例成员都不保证是线程安全的。” http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx
我似乎得到了与DataContext
相关的常见错误,并且线程安全缺乏。
我在这里解释一下我想做什么,以及我想要的结果是什么,希望得到专家对这个案例的帮助和想法。
我想对大约100,000条记录进行大量分析,
错误是:
调用了EntityMemberChanged或EntityComplexMemberChanged,而没有先在具有相同属性名称的同一更改跟踪器上调用EntityMemberChanging或EntityComplexMemberChanging。有关正确报告更改的信息,请参阅实体框架文档。
在Designer代码中指向此行:
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; }
}
安全性和数据上下文生命周期不应成为问题,因为分析处于构建阶段并且是本地的。
我做错了什么?
有什么建议吗?
类似案例中的想法或经验?
答案 0 :(得分:2)
我不知道EF,但是从问题和评论来看,我认为问题在于你不能同时从不同的线程设置ProductName
,即使它是针对不同的{{1 s(因为它们都使用相同的非线程安全的Product
)。
所以,我的建议是并行运行昂贵的操作,但是确保一次仅从一个线程设置DataContext
。实现这一目标的最简单方法是使用ProductName
:
lock
就像我说的,我不知道EF,所以我不完全理解这个问题。因此,这可能不是正确的解决方案。