Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.216.163] |
|
Сообщ.
#1
,
|
|
|
Есть некая процедура, которая выполняет некие действия, и ход их выполнения передаётся через CallBack
В своём классе от TThread, я использую эту процедуру во время Execute, и хочу что бы КолБэки хода выполнения процедуры передавались рабочему потоку, что бы он возвращал их через событие. Скажите как вам такая реализация: unit Unit1; interface uses System.Classes; type TCallBackProc = procedure(v, w: integer; obj: Pointer); TSomethingEvent = procedure(Sender: TObject; X: Integer; Y: Integer) of object; TMyThread = class(TThread) strict private class procedure Callback(v, w: integer; obj: Pointer); static; private { Private declarations } fSomethingEvent: TSomethingEvent; procedure DoNotyfySomething; protected procedure Execute; override; property OnSomething: TSomethingEvent read fSomethingEvent write fSomethingEvent ; end; implementation procedure proc(x,y: Integer; obj: Pointer; CallBackProc: TCallBackProc ); var i: integer; begin for i := 0 to 100 do CallBackProc(x+i, y+i, obj); end; class procedure MyThread.Callback(v, w: integer; obj: Pointer); begin TMyThread(obj).DoNotyfySomething(v, w); end; procedure MyThread.DoNotyfySomething(x,y: Integer); begin if not assigned(fSomethingEvent) then Exit; Synchronize( procedure begin fSomethingEvent(Self, X, Y); end); end; procedure MyThread.Execute; begin proc(10, 32, Pointer(Self), @CallBack) { Place thread code here } end; Добавлено Меня в моём коде смущает как бы внешнее обращение к потоку для вызова в нём процедуры с Synchronize. Это нормально или могут быть сбои ? |
Сообщ.
#2
,
|
|
|
Если метод (хоть потока, хоть чего) вызывается из главного потока, его тело будет выполняться в главном потоке, и синхронизация лишняя.
Вообще схема какая-то невнятная. Почему из поточной функцйии вызывается некая регулярная процедура, иcпользующая колбэк и где он назначается? |
Сообщ.
#3
,
|
|
|
Цитата MBo @ Почему из поточной функцйии вызывается некая регулярная процедура Что бы не переписывать эту процедуру делая её принадлежащей классу. Цитата MBo @ и где он назначается КолБэк назначается в Execute потока. Добавлено Цитата MBo @ синхронизация лишняя. Почему лишняя, зависать же будет GUI без синхронизации или нет ? |
Сообщ.
#4
,
|
|
|
Опиши реальную задачу.
То, что написано, не годится ни для чего. |
Сообщ.
#5
,
|
|
|
Схема вызова процедуры из Execute с callback-ом и указателем на себя нормальная. Если не нравится отдельно висяая процедура-коллбэк, ее можно засунуть в класс как class procedure static.
Только применение Synchronize мне не нравится, его стоит избегать. С другой стороны, без него при присвоении обработчика DoNotyfySomething надо постоянно помнить, что метод будет выполняться в контексте потока TMyThread. Альтернативным вариантом может послужить передача в TMyThread хэндла окна либо потока, которому по коллбэку будут отправляться сообщения. Это позволит полностью отзвязать TMyThread и не морочиться с синхронизацией, однако надо будет предусмотреть случай неудачи отправки сообщения (при переполнении очереди) |
Сообщ.
#6
,
|
|
|
Цитата Только применение Synchronize мне не нравится, его стоит избегать Конкретно тут или вобще при использовании Threads ? Цитата Fr0sT @ С другой стороны, без него при присвоении обработчика DoNotyfySomething надо постоянно помнить, что метод будет выполняться в контексте потока TMyThread. Ммм, а что это значит? Цитата Fr0sT @ Альтернативным вариантом может послужить передача в TMyThread хэндла окна либо потока, которому по коллбэку будут отправляться сообщения. Это позволит полностью отзвязать TMyThread и не морочиться с синхронизацией, однако надо будет предусмотреть случай неудачи отправки сообщения (при переполнении очереди) Не понял эту часть совсем. Цитата MBo @ Опиши реальную задачу. То, что написано, не годится ни для чего. Реальная задача такова: Есть функция без классовая, она нечто делает, ход работы отдаёт через callback. Я хочу что бы функция выполнялась в потоке, и приходили результаты её хода работы из потока через событие. Мне лень переписывать эту функцию, делая её функцией класса потока, прописывая на каждой стадии вместо вызова callback вызов события класса, что бы оповестить приложение о событии. Поэтому я ищу способ как этого избежать (т.е. переписывания) |
Сообщ.
#7
,
|
|
|
Цитата Jiro @ Конкретно тут или вобще при использовании Threads ? Вообще. Чуть расслабился и дедлок. Да и в принципе эта функция - лишь хак, чтобы не глючила связка из потока и VCL. Хотя это и не исключает того, что при корректном применении она существенно проще остальных вариантов. Цитата Jiro @ Ммм, а что это значит? Если вызывать обработчик без Synchronize, он будет выполняться в контексте MyThread. То есть весь код обработчика, пусть он и будет принадлежать, условно, FormMain, но будет по факту как выполняемый из Execute. Цитата Jiro @ Не понял эту часть совсем. Вместо коллбэка можно делать PostMessage(hwndCallbackReceiver, MSG_CALLBACK, ...). |