На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> CallBack внутри TThread
    Есть некая процедура, которая выполняет некие действия, и ход их выполнения передаётся через CallBack
    В своём классе от TThread, я использую эту процедуру во время Execute, и хочу что бы КолБэки хода выполнения процедуры
    передавались рабочему потоку, что бы он возвращал их через событие.

    Скажите как вам такая реализация:

    ExpandedWrap disabled
      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.
    Это нормально или могут быть сбои ?
      Если метод (хоть потока, хоть чего) вызывается из главного потока, его тело будет выполняться в главном потоке, и синхронизация лишняя.

      Вообще схема какая-то невнятная. Почему из поточной функцйии вызывается некая регулярная процедура, иcпользующая колбэк и где он назначается?
        Цитата MBo @
        Почему из поточной функцйии вызывается некая регулярная процедура

        Что бы не переписывать эту процедуру делая её принадлежащей классу.

        Цитата MBo @
        и где он назначается

        КолБэк назначается в Execute потока.

        Добавлено
        Цитата MBo @
        синхронизация лишняя.

        Почему лишняя, зависать же будет GUI без синхронизации или нет ?
          Опиши реальную задачу.
          То, что написано, не годится ни для чего.
            Схема вызова процедуры из Execute с callback-ом и указателем на себя нормальная. Если не нравится отдельно висяая процедура-коллбэк, ее можно засунуть в класс как class procedure static.
            Только применение Synchronize мне не нравится, его стоит избегать. С другой стороны, без него при присвоении обработчика DoNotyfySomething надо постоянно помнить, что метод будет выполняться в контексте потока TMyThread.
            Альтернативным вариантом может послужить передача в TMyThread хэндла окна либо потока, которому по коллбэку будут отправляться сообщения. Это позволит полностью отзвязать TMyThread и не морочиться с синхронизацией, однако надо будет предусмотреть случай неудачи отправки сообщения (при переполнении очереди)
            Сообщение отредактировано: Fr0sT -
              Цитата
              Только применение Synchronize мне не нравится, его стоит избегать

              Конкретно тут или вобще при использовании Threads ?

              Цитата Fr0sT @
              С другой стороны, без него при присвоении обработчика DoNotyfySomething надо постоянно помнить, что метод будет выполняться в контексте потока TMyThread.

              Ммм, а что это значит?

              Цитата Fr0sT @
              Альтернативным вариантом может послужить передача в TMyThread хэндла окна либо потока, которому по коллбэку будут отправляться сообщения. Это позволит полностью отзвязать TMyThread и не морочиться с синхронизацией, однако надо будет предусмотреть случай неудачи отправки сообщения (при переполнении очереди)

              Не понял эту часть совсем.


              Цитата MBo @
              Опиши реальную задачу.
              То, что написано, не годится ни для чего.


              Реальная задача такова:
              Есть функция без классовая, она нечто делает, ход работы отдаёт через callback.
              Я хочу что бы функция выполнялась в потоке, и приходили результаты её хода работы из потока через событие.
              Мне лень переписывать эту функцию, делая её функцией класса потока, прописывая на каждой стадии вместо вызова callback вызов события класса,
              что бы оповестить приложение о событии.
              Поэтому я ищу способ как этого избежать (т.е. переписывания)
              Сообщение отредактировано: Jiro -
                Цитата Jiro @
                Конкретно тут или вобще при использовании Threads ?

                Вообще. Чуть расслабился и дедлок. Да и в принципе эта функция - лишь хак, чтобы не глючила связка из потока и VCL. Хотя это и не исключает того, что при корректном применении она существенно проще остальных вариантов.
                Цитата Jiro @
                Ммм, а что это значит?

                Если вызывать обработчик без Synchronize, он будет выполняться в контексте MyThread. То есть весь код обработчика, пусть он и будет принадлежать, условно, FormMain, но будет по факту как выполняемый из Execute.
                Цитата Jiro @
                Не понял эту часть совсем.

                Вместо коллбэка можно делать PostMessage(hwndCallbackReceiver, MSG_CALLBACK, ...).
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0285 ]   [ 17 queries used ]   [ Generated: 24.04.24, 03:58 GMT ]