Пример:
Предположим, у меня будет следующий поток (пожалуйста, не учитывайте то, что используется в этом примере, метод выполнения контекста потока, это просто для объяснения):
type
TSampleThread = class(TThread)
private
FOnNotify: TNotifyEvent;
protected
procedure Execute; override;
public
property OnNotify: TNotifyEvent read FOnNotify write FOnNotify;
end;
implementation
procedure TSampleThread.Execute;
begin
while not Terminated do
begin
if Assigned(FOnNotify) then
FOnNotify(Self); // <- this method can be called anytime
end;
end;
Тогда предположим, что я хотел бы изменить метод события OnNotify
из основного потока в любое время, когда мне нужно. Этот основной поток реализует метод обработчика событий как метод ThreadNotify
здесь:
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
FSampleThread: TSampleThread;
procedure ThreadNotify(Sender: TObject);
end;
implementation
procedure TForm1.ThreadNotify(Sender: TObject);
begin
// do something; unimportant for this example
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FSampleThread.OnNotify := nil; // <- can this be changed anytime ?
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FSampleThread.OnNotify := ThreadNotify; // <- can this be changed anytime ?
end;
Вопрос:
Можно ли изменить метод, который можно вызвать из рабочего потока из другого контекста потока в любое время? Безопасно ли делать то, что показано в приведенном выше примере?
Я не совсем уверен, если это абсолютно безопасно, по крайней мере, поскольку указатель метода на самом деле представляет собой пару указателей, и я не знаю, могу ли я считать его как атомную операцию.