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

Ошибка доступа при вызове функций диалоговых окон в многопоточной среде Delphi XE

Delphi , Компоненты и Классы , Потоки

Ошибка доступа при вызове функций диалоговых окон в многопоточной среде Delphi XE

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

Описание проблемы

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

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  public
    text: string;
    property ReturnValue;
  end;

procedure TMyThread.Execute;
begin
  if Terminated then
    Exit;
  MessageDlgPos(text, mtInformation, [mbOk], 0, 100, 200);
end;

procedure TForm1.btnTestClick(Sender: TObject);
var
  LThread: TMyThread;
  i: Integer;
begin
  For i := 1 to 5 do
  begin
    LThread := TMyThread(Sender); // Ошибка здесь
    try
      LThread.text := 'hi';
      LThread.FreeOnTerminate := True;
    except
      LThread.Free;
      raise;
    end;
    LThread.Resume;
  end;
end;

Ошибка возникает из-за неправильного обращения к объекту Sender, который является кнопкой, а не потоком. Также в коде присутствует вызов MessageDlgPos из потока, что не допускается, так как диалоговые окна VCL должны быть вызваны только из основного потока.

Решение проблемы

Для устранения ошибки необходимо исправить следующие моменты:

  1. Создание потока вместо попытки приведения Sender к типу TMyThread.
  2. Использование TThread.Synchronize для выполнения кода в основном потоке, если необходимо показать диалоговое окно.
  3. Удаление лишнего обработчика исключений, который не имеет смысла в данном контексте.

Вот исправленный код:

type
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  public
    text: string;
  end;

procedure TMyThread.Execute;
begin
  TThread.Synchronize(nil,
    procedure
    begin
      MessageDlgPos(text, mtInformation, [mbOk], 0, 100, 200);
    end
  );
end;

procedure TForm1.btnTestClick(Sender: TObject);
var
  LThread: TMyThread;
  i: Integer;
begin
  For i := 1 to 5 do
  begin
    LThread := TMyThread.Create(True);
    LThread.text := 'hi';
    LThread.FreeOnTerminate := True;
    LThread.Start;
  end;
end;

Или альтернативный вариант создания потока:

type
  TMyThread = class(TThread)
  private
    fText: string;
  protected
    procedure Execute; override;
  public
    constructor Create(const aText: string); reintroduce;
  end;

constructor TMyThread.Create(const aText: string);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  fText := aText;
end;

procedure TMyThread.Execute;
begin
  TThread.Synchronize(nil,
    procedure
    begin
      MessageDlgPos(fText, mtInformation, [mbOk], 0, 100, 200);
    end
  );
end;

procedure TForm1.btnTestClick(Sender: TObject);
var
  i: Integer;
begin
  For i := 1 to 5 do
  begin
    TMyThread.Create('hi');
  end;
end;

Если необходимо использовать диалоговые окна, которые могут быть вызваны из любого потока, можно использовать Windows.MessageBox, который не требует делегирования в основной поток.

Заключение

При работе с многопоточностью в Delphi важно помнить, что операции с пользовательским интерфейсом должны выполняться в основном потоке. Использование TThread.Synchronize позволяет безопасно вызвать код в основном потоке, что необходимо для отображения диалоговых окон.

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

Пользователь столкнулся с ошибкой доступа в многопоточном приложении Delphi XE при попытке вызова функции диалогового окна из вторичных потоков, что является недопустимым, так как элементы пользовательского интерфейса должны обрабатываться только в основ


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

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




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


:: Главная :: Потоки ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2024-12-26 14:10:39/0.003593921661377/0