Безопасно ли разрешать двум потокам редактировать разные свойства одного и того же объекта одновременно? - PullRequest
7 голосов
/ 24 февраля 2010

Я пишу каталогизирующее приложение, которое анализирует и извлекает информацию из файлов и сохраняет информацию из каждого файла в экземпляре объекта. В дополнение к данным, извлеченным из файла, объекты также имеют дополнительные свойства метаданных (автор, теги, заметки и т. Д.), Которые впоследствии сохраняются в отдельном файле XML.

Извлечение данных из файлов является длительным процессом, поэтому он выполняется в отдельном потоке. Свойства, извлеченные из файлов, будут извлечены только из файлов и, таким образом, будут иметь атрибуты [ReadOnly], чтобы пользователь не мог их редактировать. С другой стороны, свойства метаданных заполняются только пользователем и, следовательно, не только для чтения. Я разрешаю пользователю просматривать / редактировать эти объекты через PropertyGrid.

Таким образом, если процесс извлечения выполняется в одном потоке, заполняющем свойства файла объекта, есть ли опасность, что пользователь может одновременно редактировать свойства метаданных? Я пытаюсь решить, должен ли я использовать модальный интерфейс, который запрещает пользователю делать что-либо до тех пор, пока извлечение не будет завершено / отменено, или немодальный интерфейс, который позволяет им продолжать работать, пока извлечение выполняется.

Ответы [ 4 ]

3 голосов
/ 24 февраля 2010

Если быть конкретным, ваш вопрос: нет, нет проблем.

То, на что вам следует обратить внимание, это то, что ваши свойства, написанные фоновым потоком, не читаются из потока пользовательского интерфейса во время записи. Если вы не можете гарантировать это, вы должны либо использовать блокировки, либо выполнить запись в поток пользовательского интерфейса. (используя control.Invoke() или BackgroundWorker или убедитесь, что запись является атомарной записью указателя на объект, который не редактируется фоновым потоком, пока он виден из потока пользовательского интерфейса. Я бы не предполагал, что стандартные контейнеры, такие как List<T> потокобезопасен.

[текст изменен]

1 голос
/ 24 февраля 2010

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

1 голос
/ 24 февраля 2010

Предполагая «нормальные» свойства - например, автоматически реализуемые или простые полевые:

public class MyClass {
    [ReadOnly]
    public string FileAuthor { get; set; }

    public string MetaDataAuthor { 
       get { return _metaDataAuthor; }
       set {  _metaDataAuthor = value; }
    }
    private string  _metaDataAuthor;
}

Не должно быть проблем, связанных с изменением значений в разных потоках. Нет необходимости синхронизировать запись в разные переменные.

Однако - если PropertyGrid показывает свойства файла (например, FileAuthor) - возможно, вы захотите синхронизировать чтение (связывание PropertyGrid) и запись (извлечение файла) из них.

1 голос
/ 24 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...