开发者

LINQ Changeset multi-threading

I'm using LINQ to SQL and after I submit some changes I want to spawn a thread which looks through all the changes and updates our lucene index as necessary. My code looks vaguely like:

(new Thread(() => { UpdateIndex(context.G开发者_Python百科etChangeSet()); }).Start();

Sometimes though I get an InvalidOperationException, which I think is because context.GetChangeSet() is not thread-safe, and so if the change set is modified in one thread while another thread is enumerating through it, problems arise.

Is there a "thread-safe" version of GetChangeSet()? Or some way I can do ChangeSet.clone() or something?


Instance members of the DataContext class are not thread-safe.

In order to avoid race conditions you should invoke the DataContext.GetChangeSet method from the same thread that makes the modifications tracked by the DataContext instance. For example:

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); 
    }
}

This assumes that the Insert and Delete methods are being called on a given instance of the CustomerDao class from a single thread.


I only needed to extract a small amount of data from each object, so for I ended up just extracting the text, putting it into a new object, then sending that new object off. This saved me a lot of trouble from having to deal with locking everywhere else, but I think Enrico's answer is probably the "real" one, so leaving his marked as the solution.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜