2015-08-26 1 views
0

Я пишу пользовательский класс, который должен иметь возможность подключения к компоненту TMemo FireMonkey в форме, чтобы записывать в него информацию. Класс определяется как:Безопасность нитей в пользовательском классе при доступе к компоненту FireMonkey

TBlokData = class 
private 
    [weak] FLogMemo: TMemo; 
    procedure Log(s : string); 
public 
    constructor Create(ConnStr: string); 
    property LogMemo : TMemo read FLogMemo write FLogMemo; 
    destructor Destroy; override; 
end; 

и реализация метода Log является:

procedure TBlokData.Log(s : string); 
begin 
    if Assigned(FLogMemo) then 
     FLogMemo.Lines.Add(TimeToStr(Now) + ': ' + s); 
end; 

Я обеспокоен, если я создаю объект класса в потоке и заполнения LogMemo свойство, скажем, компонент Memo1 в форме FireMonkey, что мой класс больше не будет потокобезопасным, потому что я буду манипулировать компонентом в форме из потока при вызове метода Log.

Является ли это актуальной проблемой? Если да, то как я могу сделать это потокобезопасным, сохраняя при этом удобство использования класса за пределами потоковой среды?

ответ

1

Создание метода LogThreadSafe:

TThread.Synchronize(nil, procedure 
    begin 
     Log(s); 
    end); 
+1

Не синхронизируется уже проверяет идентификатор потока? Нет проверки дважды. –

+0

http://docwiki.embarcadero.com/Libraries/XE8/en/System.Classes.TThread.Synchronize: "** Предупреждение: ** Не вызывать Синхронизацию из основного потока. Это может вызвать бесконечный цикл. " – Wosi

+1

Эта документация неверна. 'TThread.Synchronize' проверяет идентификатор потока, и если мы находимся в основном потоке, он просто вызывает метод напрямую и возвращается. Пропустить 'TThread.CurrentThread' немного бессмысленно. Лучше передать 'nil'. –

1

Вы имеете право на беспокойство. Ваш код не является потокобезопасным. Используйте TThread.Synchronize или TThread.Queue, чтобы гарантировать, что любые манипуляции с пользовательским интерфейсом выполняются в основном потоке пользовательского интерфейса.

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

+0

Как я должен выполнять фоновые задачи, работающие за пределами UI Thread? – Machado

Смежные вопросы