Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TThread.Queue для старых версий delphi 
:(
    Опции темы
Чучмек
Дата 8.9.2013, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 14
Всего: 41



Вчера стала задача - выполнить определенное действие (процедура завершения) гарантированно после отработки потока.
Причем инициализация этого действия должна осуществляться из самого потока.
Посмотрев список методов TThread сразу нашел Queue.  Как Synchronize, только асинхронно.
Все ок, только вот когда потребовалось скомпилить в D7 (требование заказчика), то случилось вполне ожидаемое - нет в D7 у потоков такого метода.
Вот слепил  на скорую руку заглушку.
Может кому пригодится.
Код

unit TThreadPatch;

interface

uses
  forms,classes,windows,messages;

type
 TThread = class (classes.TThread)
 protected
   procedure Queue(AMethod: TThreadMethod);
 end;
implementation

const
  WM_QUEUE = WM_USER + $200;

type
  TMethodAsDWDW = record
     case Integer of
     1:(
        Method:TMethod;
        );
     2:(
        ThreadMethod:TThreadMethod;
        );
     3:(
        DW1,
        DW2:WPARAM
        );
   end;

{ TThread }

procedure TThread.Queue(AMethod: TThreadMethod);
var
  MethodAsDWDW:TMethodAsDWDW;
begin
  MethodAsDWDW.ThreadMethod:=AMethod;
  PostMessage(Application.Handle,WM_QUEUE,MethodAsDWDW.DW1,MethodAsDWDW.DW2);
end;



var
  ApplicationOldWNDPROC:function(HWND:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
function ApplicationWNDPROC(HWND:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT; stdcall;
var
  MethodAsDWDW:TMethodAsDWDW;
begin
  if (HWND = Application.Handle) and (Msg = WM_QUEUE) then
  begin
    MethodAsDWDW.DW1:=wParam;
    MethodAsDWDW.DW2:=lParam;
    MethodAsDWDW.ThreadMethod;
  end;
  result:=ApplicationOldWNDPROC(HWND,Msg,wParam,lParam);
end;

initialization
  ApplicationOldWNDPROC:=Pointer(GetWindowLong(Application.Handle,GWL_WNDPROC));
  SetWindowLong(Application.Handle,GWL_WNDPROC,Integer(@ApplicationWNDPROC));
end.





Добавляем в uses после classes и все.

Это сообщение отредактировал(а) Чучмек - 8.9.2013, 19:55


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Poseidon
Дата 8.9.2013, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Чучмек @  8.9.2013,  19:38 Найти цитируемый пост)
выполнить определенное действие (процедура завершения) гарантированно после отработки потока.
Не совсем ясна цель асинхронности, если все это нужно сделать после отработки потока. Как раз Synchronize или OnTerminate тут бы подошли не хуже Queue. Ну а что касается непосредственно Queue в ранних Delphi, то, помниться, там этот вопрос решался так же через PostMessage.


Это сообщение отредактировал(а) Poseidon - 8.9.2013, 20:27


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Чучмек
Дата 8.9.2013, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЭТ БИЛЭТ
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 11.5.2008
Где: СССР

Репутация: 14
Всего: 41



Цитата(Poseidon @  8.9.2013,  20:24 Найти цитируемый пост)
или OnTerminate

В том и дело, что OnTerminate вызывается через Synchronize.
Цитата

procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
 
А в вызываемом методе, в моем случае, стоит WaitFor.

Цитата

в моем случае
  
Мой случай - две кнопки. Одна создает поток, другая завершает. Плюс  у кнопок соответственно меняется enabled.
Но поток может завершится и "сам" - по ошибке. При "самостоятельном" завершении должен выполнится обработчик кнопки "стоп".
Как-то так.
Знаю. Можно было бы извернутся десятью другими способами.    


--------------------
умную мысль держи при себе, а дурной - поделись с другими 
PM MAIL   Вверх
Poseidon
Дата 8.9.2013, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Чучмек @  8.9.2013,  22:03 Найти цитируемый пост)
В том и дело, что OnTerminate вызывается через Synchronize.
Это верно, но это не имеет значения (в большинстве случаев) если речь идет о вызове после отработки потока.

Цитата(Чучмек @  8.9.2013,  22:03 Найти цитируемый пост)
в вызываемом методе, в моем случае, стоит WaitFor.
Вот при этому условии уже другой разговор. Тут явно нужна асинхронизация. Но если в этом твоем методе убрать WaitFor и засунуть его (метод) в OnTerminate, то, думаю, результат будет тот же.


Я не в коем случае не хочу раскритиковать твой код и сказать что это лажа. Код хороший. Другое дело в том, что ты наткнулся на проблему отсутствия в старом Delphi метода, которого там нет и (самое главное) без которого можно было бы вообще обойтись. Т.е. получилось так, что сам себе придумал сложность и попытался ее решить. Да, это похвально. Но правильнее было бы не натыкаться на такую сложность. Другими словами, ты показал общественности как можно решить вопрос отсутствия метода Queue в D7, я же хочу указать лишь на то, что конкретно в твоем случае нет особой нужды использовать этот метод. (Если честно, я вообще не понимаю смысла вызывать при завершении потока метод, который вызывает WaitFor этого потока. Используй OnTerminate, он гарантированно вызовется только при завершении потока. И не нужно ничего ждать вэйтвором). В другом же случае, где использование Queue было бы действительно оправдано, твой код может кому-то и пригодиться.  smile 


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
MetalFan
Дата 10.9.2013, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Poseidon @  8.9.2013,  22:20 Найти цитируемый пост)
это не имеет значения (в большинстве случаев) если речь идет о вызове после отработки потока

полностью согласен. Не вижу смысла в пляске с бубном вокруг реализации Queue для D7 для данного случая.



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1142 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.