并行迭代上下文

时间:2012-06-24 13:58:50

标签: c# entity-framework parallel-processing task-parallel-library

据我所知,在并行中使用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; } 
     }

安全性和数据上下文生命周期不应成为问题,因为分析处于构建阶段并且是本地的。

我做错了什么?

有什么建议吗?

类似案例中的想法或经验?

1 个答案:

答案 0 :(得分:2)

我不知道EF,但是从问题和评论来看,我认为问题在于你不能同时从不同的线程设置ProductName,即使它是针对不同的{{1 s(因为它们都使用相同的非线程安全的Product)。

所以,我的建议是并行运行昂贵的操作,但是确保一次仅从一个线程设置DataContext。实现这一目标的最简单方法是使用ProductName

lock

就像我说的,我不知道EF,所以我不完全理解这个问题。因此,这可能不是正确的解决方案。