As I understand Working with a DataContext in Parallel is not thread-safe but only if you declare your context as static (Based on MSDN documentation)
This is what I did, once I found it worked and the other time it failed !
MSDN :
Thread Safety
“Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.”
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx
It seems that I’m getting the usual error related to DataContext and it’s Thread-Safety lack.
Here I explain a bit what I want to do, and what is my desired result, hope got expert’s help and ideas on this case.
I want to do heavy analysis processes on about 100,000 records,
The error is :
EntityMemberChanged or EntityComplexMemberChanged was called without first calling EntityMemberChanging or EntityComplexMemberChanging on the same change tracker with the same property name. For information about properly reporting changes, see the Entity Framework documentation.
Pointing to this line in the Designer code :
ReportPropertyChanged("ProductName");
What is in my Code :
//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; }
}
Security and Data Context Life-time shouldn’t be a problem cause the the analysis is in the build-phase and it’s local.
What I did wrong?
Any suggestions?
Ideas or experiences in similar cases?
I don’t know EF, but from the question and comments, I think the problem is that you can’t set
ProductNamefrom different threads at the same time, even if it is for differentProducts (because they all use the same non-thread-safeDataContext).So, my advice is to run the expensive operation in parallel, but then make sure to set
ProductNameonly from one thread at a time. The simplest way to achieve that is to use alock:Like I said, I don’t know EF, so I don’t fully understand the problem. Because of that, this might not be the right solution.