Jump to content
andrey.b

Calling Async from a thread causes an exception

Recommended Posts

Hello everybody,

 

I'm a novice with the OTL. And I've written a simple app to experiment with it. But it causes the EOSError with the "System Error. Code: 1400. Invalid window handle." message in the TOmniContainerWindowsMessageObserverImpl.PostWithRetry method. Could anybody explain what is wrong with my code and (if it is not correct) provide a fix or solution?

 

I use Delphi 10.2.3 (Tokyo) and OTL 3.07.9.

 

Any help is appreciated.

 

This is my code:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  OtlParallel;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      Parallel.Async(
        procedure
        begin
          Sleep(100);
        end);
    end).Start;
end;

end.

 

Share this post


Link to post
Guest

I'm guessing your Form1 doesn't have a window handle yet in its OnCreate event. Try calling HandleNeeded before creating the thread, or move your code to OnShow or somewhere else where the form already has been initialized including the window handle.

Share this post


Link to post

Thanks for the reply, Ondrej! I have just added a Button to the form and placed the code in the OnClick handler. Unfortunately, the problem still exists. The new code is:

 

procedure TForm1.Button1Click(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      Parallel.Async(
        procedure
        begin
          Sleep(100);
        end);
    end).Start;
end;

 

Share this post


Link to post

It was just for demo or testing purposes. Now I know that it fails because the Anonymous thread is destroyed sooner than the async procedure ends. The possible workaround is to add some delay, like Sleep(1000), after calling the TThread.CreateAnonymousThread(...).Start method.

Edited by andrey.b

Share this post


Link to post

Yes, it fails because the owner (anonymous thread) is destroyed before the worker (Parallel.Async). You could also run into problems because the owner thread is not processing Windows messages, which is a requirement for threads that own OTL tasks. Not in this simple example, but as soon as you start sending messages towards the owner or using OnTerminate handlers you would run into trouble.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×