Рекомендации по безопасности потоков при использовании DataGridView и BindingList в C # - PullRequest
2 голосов
/ 06 октября 2009

Я пишу класс для регистрации событий. Мой LogClass реализован как одноэлементный, и любой класс в системе может записать запись в журнал. Записи хранятся в списке, а когда буфер заполняется, они выгружаются на диск.

Я использую DataGridView для отображения содержимого LogClass во время выполнения, поэтому я использовал BindingList, чтобы средство просмотра обновлялось автоматически.

Мне интересно, насколько безопасен мой класс. Я использую «блокировку» каждый раз, когда добавляю новую запись в список, и когда я перебираю список, чтобы записать ее на диск. Помимо DataGridView, класс в основном только для записи, потому что нет опции для чтения из журнала, только для добавления записей в журнал. Дамп выполняется внутренне, и это единственный раз, когда в BindingList есть явная команда чтения.

Итак, меня действительно беспокоит то, что происходит с DataGridView и BindingList? BindingList генерирует событие при каждом изменении списка. Это не похоже на проблему при добавлении новых записей, потому что событие выбрасывается, когда добавление завершено.

Мой код для Dump ():

lock (lockObj) {
    foreach (LogEntry le in List) {
      writeToDisk(le)
      removeFromList(le)
    }
 }

Несмотря на то, что я блокирую список на протяжении всей итерации, в Viewer выдается событие, которое изменило список (из-за удаления) и, следовательно, читается DataGridView. Я действительно не хочу ничего читать / писать в список, пока я его изменяю. Есть идеи?

Ответы [ 2 ]

1 голос
/ 29 октября 2009

На самом деле это не проблема, поскольку после привязки вы можете изменить список только из метода Form.Invoke (унаследованного от Control.Invoke). Если вы попытаетесь изменить список из другого потока, среда выполнения .NET будет лаять на ваше исключение, говоря что-то вроде «невозможно изменить этот список из текущего потока».

В этом есть код, который вы можете получить.

С уважением, = Alan

1 голос
/ 24 октября 2009

Я думал, что BindingList не реализовал уведомление об изменении. В этом сценарии я не думаю, что это потокобезопасно.

Решением может быть использование пользовательской коллекции, которая реализует IBindingList, и изменение средства доступа к списку для получения блокировки перед возвратом любого элемента.

У меня есть пользовательская реализация IBindingList с уведомлением об изменениях, поэтому, если вы хотите, я могу поделиться этим (возможно, я все равно напишу статью о проекте кода, описывающую реализацию).

...