我正在使用LINQ to SQL,在提交一些更改后,我想生成一个线程,该线程查看所有更改并在必要时更新lucene索引。我的代码看起来有点像:
(new Thread(() => { UpdateIndex(context.GetChangeSet()); }).Start();有时我会得到一个InvalidOperationException,我认为这是因为context.GetChangeSet()不是线程安全的,所以如果更改集在一个线程中被修改,而另一个线程正在枚举它,那么问题就出现了。
GetChangeSet()有没有“线程安全”的版本?或者我可以用某种方式做ChangeSet.clone()或者别的什么?
发布于 2010-05-26 05:25:02
DataContext类的实例成员不是线程安全的。
为了避免竞争条件,您应该从进行DataContext实例跟踪的修改的同一线程中调用DataContext.GetChangeSet方法。例如:
public class CustomerDao : IDisposable
{
private DataContext context;
public CustomerDao()
{
this.context = new DataContext("SomeConnectionString");
}
public void Insert(Customer instance)
{
this.context.Customers.InsertOnSubmit(instance);
this.StartUpdateIndex();
this.context.SubmitChanges();
}
public void Delete(Customer instance)
{
this.context.Customers.DeleteOnSubmit(instance);
this.StartUpdateIndex();
this.context.SubmitChanges();
}
public void Dispose()
{
if (this.context != null)
{
this.context.Dispose();
}
}
private void StartUpdateIndex()
{
ChangeSet changes = this.context.GetChangeSet();
ThreadPool.QueueUserWorkItem(
state => this.UpdateIndex((ChangeSet)state), changes);
}
}这假设从单个线程对CustomerDao类的给定实例调用Insert和Delete方法。
发布于 2010-05-26 22:22:38
我只需要从每个对象中提取少量数据,所以我最终只需要提取文本,将其放入一个新对象中,然后发送该新对象。这为我节省了很多麻烦,使我不必在其他地方处理锁定问题,但我认为Enrico的答案可能是“真正的”答案,所以留下他的标记作为解决方案。
https://stackoverflow.com/questions/2908132
复制相似问题