Доступ Delphi к переменным потока - PullRequest
1 голос
/ 07 октября 2010

У меня есть поток, который выполняет запрос WMI для меня, и мне нужно получить доступ к некоторым переменным в потоке после того, как он выполнил запрос.

Тема создается следующим образом ...

procedure TFormMain.RunThread;
var
  WMIQ: TThreadWmiQuery;
begin
  WMIQ := TThreadWmiQuery.Create(True);
  ...
  WMIQ.OnTerminate := WMIQThreadOnTerminate;
  WMIQ.Resume;
end;

и в событии OnTerminate я получаю значения, которые мне нужны, например ...

procedure TFormMain.WMIQThreadOnTerminate(Sender: TObject);
begin
  Opcd := TThreadWmiQuery(Sender).P4COpcd;
  Role := TThreadWmiQuery(Sender).P4CRole;
  Usnm := TThreadWmiQuery(Sender).P4CUsnm;
end;

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

С уважением, Питер

Ответы [ 3 ]

4 голосов
/ 07 октября 2010

Кто тебе это сказал? Они дали какие-либо причины?

OnTerminate предназначен для запроса экземпляра потока после того, как он завершит выполнение и до того, как он будет уничтожен. Фактически, когда вы устанавливаете TThread's FreeOnTerminate в True, у вас нет другого места для доступа к переменным потока.

Другие механизмы:

  • глобальная переменная, установленная потоком, запрашивается в другом месте: yuck, и вам все равно нужно будет использовать onterminate, чтобы узнать, когда завершится поток. Лучше хранить переменные локальными для самого потока.

  • с использованием PostThreadMessage из ветки: но куда писать? Это будет означать, что ветка узнает, кому отправлять эти сообщения, и, следовательно, что-то вроде механизма наблюдения.

Первым я бы не советовал. Второе ИМХО является излишним, если вам просто нужно запросить пару значений после завершения потока.

1 голос
/ 07 октября 2010

Я не вижу ничего плохого в вашем коде, где нет необходимости его улучшать.Но если вы все еще хотите улучшить его, обратите внимание, что код TThread.OnTerminate выполняется в контексте основного потока с использованием TThread.Syncronize.Это означает, что ваш WMIQThread переходит в состояние ожидания, спит до тех пор, пока основной поток не выполнит код TThread.OnTerminate, не проснется и не завершится.Для такой синхронизации не требуется просто назначать переменные потока, поэтому код может быть улучшен, но улучшение должно быть реализовано в методах TThreadWmiQuery.

Если вы не хотите изменять реализацию TThreadWmiQuery, просто оставьтевещи как есть.

1 голос
/ 07 октября 2010

Я не вижу проблем с этим подходом.

Единственное место, где вы храните ссылку на объект потока, находится в локальной переменной, поэтому объект потока недоступен во время работы.Это хорошо;это означает, что ничто не может получить доступ к открытым свойствам или полям потока, пока поток не завершит вычисление их значений.

Убедитесь, что вы освободили объект потока где-то.Вы можете сделать это, установив его свойство FreeOnTerminate в своем конструкторе.

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