LINQ Changeset многопоточность

Я использую LINQ для SQL и после того, как я отправляю некоторые изменения, я хочу породить поток, который просматривает все изменения и обновляет наш индекс lucene по мере необходимости. Мой код смотрит неопределенно как:

(new Thread(() => { UpdateIndex(context.GetChangeSet()); }).Start();

Иногда, хотя я получаю InvalidOperationException, который я думаю, то, потому что контекст. GetChangeSet () не ориентирован на многопотоковое исполнение, и поэтому если массив изменений изменяется в одном потоке, в то время как другой поток перечисляет через него, проблемы возникают.

Существует ли "ориентированная на многопотоковое исполнение" версия GetChangeSet ()? Или некоторый путь я могу сделать ChangeSet.clone () или что-то?

1
задан Xodarap 25 May 2010 в 20:06
поделиться

2 ответа

Члены экземпляра класса DataContext не являются потокобезопасными.

Чтобы избежать условий гонки, следует вызывать метод DataContext.GetChangeSet из того же потока, который производит изменения, отслеживаемые экземпляром DataContext. Например:

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

Здесь предполагается, что методы Insert и Delete вызываются на данном экземпляре класса CustomerDao из одного потока.

2
ответ дан 3 September 2019 в 00:18
поделиться

Мне нужно было извлечь только небольшое количество данных из каждого объекта, так что в итоге я просто извлек текст, поместил его в новый объект, а затем отправил этот новый объект. Это избавило меня от необходимости возиться с блокировкой в других местах, но я думаю, что ответ Энрико, вероятно, является "настоящим" ответом, поэтому оставляю его как решение.

0
ответ дан 3 September 2019 в 00:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: