Действительно ли безопасно позволить двум потокам редактировать различные свойства того же объекта одновременно?

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

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

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

8
задан mghie 24 February 2010 в 20:58
поделиться

4 ответа

В частности, к вашему вопросу: Нет, проблем нет.

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

[формулировка изменена]

4
ответ дан 5 December 2019 в 21:18
поделиться

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

1
ответ дан 5 December 2019 в 21:18
поделиться

Что-то подобное?

http://www.sveinbjorn.org/dataurls_css

-121--1648132-

Существует несколько подходов:

Использование ActiveSupport:: Concern (предпочтительно)

Для получения дополнительной информации см. документацию ActiveSupport:: Concern .

Создайте файл с именем active _ record _ extension.rb в каталоге lib .

require 'active_support/concern'

module ActiveRecordExtension

  extend ActiveSupport::Concern

  # add your instance methods here
  def foo
     "foo"
  end

  # add your static(class) methods here
  class_methods do
    #E.g: Order.top_ten        
    def top_ten
      limit(10)
    end
  end
end

# include the extension 
ActiveRecord::Base.send(:include, ActiveRecordExtension)

Создайте файл в каталоге config/initializers с именем extensions.rb и добавьте в файл следующую строку:

require "active_record_extension"

Наследование (предпочтительно)

См. ответ Тоби .

Исправление обезьян (следует избегать)

Создайте файл в каталоге config/initializers с именем active _ record _ monkey _ patch.rb .

class ActiveRecord::Base     
  #instance method, E.g: Order.new.foo       
  def foo
   "foo"
  end

  #class method, E.g: Order.top_ten        
  def self.top_ten
    limit(10)
  end
end

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

Некоторые люди, столкнувшись с проблемой, думают: "Я знаю, я буду использовать исправление обезьян. " Сейчас у них две проблемы.

Исправление обезьян просто и быстро. Но сэкономленные время и усилия всегда извлекаются обратно где-то в будущем; с комплексным интересом. В эти дни я ограничиваю заплатку обезьян, чтобы быстро создать прототип решения в консоли рельсов.

-121--661810-

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

1
ответ дан 5 December 2019 в 21:18
поделиться

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

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
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

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