Синхронизировать datatable / dataview для чтения и записи - PullRequest
1 голос
/ 04 мая 2010

У меня есть приложение в .net 2.0, в котором у меня есть объект DataTable глобально в моем приложении и разные представления данных во всем приложении.

Когда выполняемое действие создает много потоков, скажем, 5, в которых данные считываются из разных видов данных, в то время как 2/3 потока читают данные (не все еще 2 оставлены для чтения данных), поток записывает данные в datatable. Таким образом, мы получаем исключения типа «Обновление перечисления» или «параметр не нулевой».

Я использую ReadWriteLock для этого, но не могу повезти, он останавливается на ReaderWriterLock.AcquireWriterLock ().

Я не понимаю, где я делаю неправильно.

Если у кого-нибудь есть идеи. Пожалуйста, помогите мне, как реализовать ReaderWriterLock для этого сценария для datatable и dataview.

Спасибо !!

1 Ответ

0 голосов
/ 05 мая 2010

Для начала, эта статья MSDN может помочь. Библиотека, о которой говорит Джеффри Рихтер, доступна здесь .

Поскольку приложение разрабатывается в .Net 2.0, я рекомендую использовать специальный ReaderWriterLock, который предпочитает писателей читателям. Кроме того, если вы ищете какой-нибудь исходный код, этот парень может быть вам полезен. Один из пользовательских ReaderWriterLock, он написал:

public sealed class ReaderWriterLock
{
    int readers = 0;
    int writers = 0;

    public void AcquireReaderLock()
    {
        Thread.BeginCriticalRegion();

        while (true)
        {
            if (Thread.VolatileRead(ref writers) == 0)
            {
                Interlocked.Increment(ref readers);

                if (Thread.VolatileRead(ref writers) == 0)
                {
                    return;
                }
                else
                {
                    Interlocked.Decrement(ref readers);
                }
            }

            Thread.Sleep(1);
        }
    }
    public void ReleaseReaderLock()
    {
        Interlocked.Decrement(ref readers);

        Thread.EndCriticalRegion();
    }
    public void AcquireWriterLock()
    {
        Thread.BeginCriticalRegion();

        while (Interlocked.CompareExchange(ref writers, 1, 0) != 0)
        {
            Thread.Sleep(1);
        }
        while (Thread.VolatileRead(ref readers) != 0)
        {
            Thread.Sleep(1);
        }
    }
    public void ReleaseWriterLock()
    {
        Thread.VolatileWrite(ref writers, 0);

        Thread.EndCriticalRegion();
    }
}

Ключевые моменты:

  1. Предпочитает писателей, а не читателей
  2. первым пришел, первым обслужен
  3. Спин-блокировка, используемая таким образом, идеально подходит только для коротких периодов блокировки
...