Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

"Многопоточность в Delphi: выполнение вызова веб-службы в рабочем потоке и оповещение главного потока из датамодуля"

Delphi , ОС и Железо , Справочник по сообщениям

Многопоточность в Delphi: выполнение вызова веб-службы в рабочем потоке и оповещение главного потока из датамодуля

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

Проблема

У нас есть датамодуль, не имеющий своего окна, и мы хотим выполнить вызов веб-службы в рабочем потоке и затем оповестить главный поток о результате. В основном потоке у нас есть форма с приватным полем (приватная строка), в которое рабочий поток будет записывать результат вызова веб-службы. После завершения вызова веб-службы рабочий поток должен уведомить главный поток о том, что результат готов.

Решение

Для решения этой проблемы мы можем использовать подход с сообщениями (PostMessage) или Events. Рассмотрим оба подхода.

1. Подход с сообщениями

Для отправки сообщений из рабочего потока в главный поток мы можем использовать функцию PostMessage. Чтобы это сделать, нам нужно иметь доступ к оконной процедуре главного потока. Однако, датамодуль не имеет своего окна и, следовательно, не имеет оконной процедуры. В этом случае мы можем использовать функцию AllocateHwnd, чтобы создать скрытое окно и использовать его оконную процедуру для приема сообщений.

Вот пример кода, демонстрирующий этот подход:

type
  TMyDataModule = class(TDataModule)
  private
    FWorkerThread: TMyThread;
    FWebServiceResponseXML: TWebServiceResponseXML;
    FWinHandle: HWND;
    procedure OnWebServiceCallComplete(var Message: TMessage);
  public
    procedure StartWorkerThread;
  end;

  TMyThread = class(TThread)
  private
    FResponseXML: TWebServiceResponseXML;
    FWinHandle: HWND;
  protected
    procedure Execute; override;
  public
    constructor Create(WinHandle: HWND);
  end;

constructor TMyThread.Create(WinHandle: HWND);
begin
  inherited Create(False);
  FWinHandle := WinHandle;
end;

procedure TMyThread.Execute;
begin
  inherited;
  CoInitialize(nil);
  try
    // Выполняем вызов веб-службы и записываем результат в FResponseXML
    PostMessage(FWinHandle, WM_WEBSERVCALL_COMPLETE, 0, 0);
  finally
    CoUninitialize;
  end;
end;

procedure TMyDataModule.StartWorkerThread;
begin
  FWinHandle := AllocateHWND(nil);
  FWorkerThread := TMyThread.Create(FWinHandle);
  FWorkerThread.FreeOnTerminate := True;
  FWorkerThread.Resume;
end;

procedure TMyDataModule.OnWebServiceCallComplete(var Message: TMessage);
begin
  // Обрабатываем результат вызова веб-службы в FWebServiceResponseXML
end;

2. Подход с Events

В качестве альтернативы подходу с сообщениями, мы можем использовать Events для оповещения главного потока о завершении вызова веб-службы. Для этого нам нужно добавить событие в класс рабочего потока и вызвать его в методе Execute после завершения вызова веб-службы.

Вот пример кода, демонстрирующий этот подход:

type
  TMyDataModule = class(TDataModule)
  private
    FWorkerThread: TMyThread;
    FWebServiceResponseXML: TWebServiceResponseXML;
    procedure OnWebServiceCallComplete(Sender: TObject);
  public
    procedure StartWorkerThread;
  end;

  TMyThread = class(TThread)
  private
    FResponseXML: TWebServiceResponseXML;
    FOnWebServiceCallComplete: TNotifyEvent;
  protected
    procedure Execute; override;
  public
    property OnWebServiceCallComplete: TNotifyEvent read FOnWebServiceCallComplete write FOnWebServiceCallComplete;
  end;

procedure TMyThread.Execute;
begin
  inherited;
  CoInitialize(nil);
  try
    // Выполняем вызов веб-службы и записываем результат в FResponseXML
    if Assigned(FOnWebServiceCallComplete) then
      FOnWebServiceCallComplete(Self);
  finally
    CoUninitialize;
  end;
end;

procedure TMyDataModule.StartWorkerThread;
begin
  FWorkerThread := TMyThread.Create(False);
  FWorkerThread.FreeOnTerminate := True;
  FWorkerThread.OnWebServiceCallComplete := OnWebServiceCallComplete;
  FWorkerThread.Resume;
end;

procedure TMyDataModule.OnWebServiceCallComplete(Sender: TObject);
begin
  // Обрабатываем результат вызова веб-службы в FWebServiceResponseXML
end;

Заключение

В этой статье мы рассмотрели два подхода к оповещению главного потока о завершении вызова веб-службы в рабочем потоке из датамодуля: подход с сообщениями и Events. Каждый из этих подходов имеет свои преимущества и недостатки, и выбор между ними зависит от конкретных требований вашего проекта.

Создано по материалам из источника по ссылке.

В данном контексте рассматривается использование многопоточности в Delphi для выполнения вызова веб-службы в рабочем потоке и оповещения главного потока из датамодуля о результате выполнения.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Справочник по сообщениям ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:37:19/0.003849983215332/0