Jump to content
chmichael

Error 1400

Recommended Posts

Hello,

  When i'm closing the application eg, after 30 seconds OTL will raise an exception with error code 1400 invalid window handle. Any ideas ?

 

Thank you

 

Code: 

var
  FTask1: IOmniTimedTask;
  FTask2: IOmniTimedTask;

procedure StartTimedTasks(const Task: IOmniTask);
begin
  FTask1 := Parallel.TimedTask.Every(1000).Execute(DoSometing1);
  FTask2 := Parallel.TimedTask.Every(1000).Execute(DoSometing2);
end;

procedure TFormApplication.FormShow(Sender: TObject);
begin
  Parallel.Async(StartTimedTasks);
end;

 

Edited by chmichael

Share this post


Link to post

I recently started using Parallel.TimedTask and now when I close the application I get the same error in completely random mode. I can't simulate the problem in a small project. I'm using D11.3 and the latest OTL version. Some idea?

Share this post


Link to post

Do you stop the tasks and wait for completion of any running task before stopping the application?

  • Like 1

Share this post


Link to post
1 hour ago, Lars Fosdal said:

Do you stop the tasks and wait for completion of any running task before stopping the application?

Before posting I tried several solutions, some of these suggested in this post: 

 

According to Primoz OTL book it seems to be enough to assign the IOmniTimedTask instance to nil to get the call to Terminate(INFINITE) and Terminate should stop the task... This works perfectley in a little sample demo. In my case leads to random errors (the app is very complex).

 

I've tried calling the Stop method and then assign the instance to nil but I get the random errors too.

 

I've tried calling also Stop + Terminate(INFINTE) + WaitFor(INFINITE) + assigning to nil without results

 

 

Edited by Davide Angeli

Share this post


Link to post
12 hours ago, Davide Angeli said:

Before posting I tried several solutions, some of these suggested in this post: 

 

According to Primoz OTL book it seems to be enough to assign the IOmniTimedTask instance to nil to get the call to Terminate(INFINITE) and Terminate should stop the task... This works perfectley in a little sample demo. In my case leads to random errors (the app is very complex).

 

I've tried calling the Stop method and then assign the instance to nil but I get the random errors too.

 

I've tried calling also Stop + Terminate(INFINTE) + WaitFor(INFINITE) + assigning to nil without results

 

 

Could you run  the app in debugger and put break points at the end of DoSometing1 and DoSometing2, and be sure that you exit from them cleanly?

 

-Tee-

Share this post


Link to post
2 hours ago, Tommi Prami said:

Could you run  the app in debugger and put break points at the end of DoSometing1 and DoSometing2, and be sure that you exit from them cleanly?

It's not so easy to debug this;  when I debug and put breakpoints inside threads, thanking our beloved IDE, I get often debugger freezes. 

 

In my case "DoSomething" code is a simple rest call (I use WiRL client to send data to WiRL server); the rest call is incapsulated in a try except to avoid errors.

 

Til now my "DoSomething" was an anonymous method. Now I've changed my code and I pass a normal procedure to timedtask.execute. Things seem to going better but I don't think this was the cause of the error.

Share this post


Link to post

If a REST call is in progress when you terminate - will the code hangup and close the REST related thread(s) ?

  • Like 1

Share this post


Link to post
35 minutes ago, Lars Fosdal said:

If a REST call is in progress when you terminate - will the code hangup and close the REST related thread(s) ?

I rely on the fact that by calling the stop method it waits and completes any ongoing operations. When the application ends, each TimedTask is stopped and its end is awaited. But in fact, if the REST execution is asynchronous, this might still be running. I don't know how the WiRL client works at a low level. Now I'll delve deeper.

Share this post


Link to post
28 minutes ago, Davide Angeli said:

I don't know how the WiRL client works at a low level. Now I'll delve deeper.

WiRL client seems using THTTPClient.Get and then THTTPClient.DoExecute to execute my REST operation (a PATCH). So I suppose that it is synchronous.

Share this post


Link to post
1 hour ago, Lars Fosdal said:

Does this trick have any effect?

I abandoned that trail: the problem is not the REST call. I've substituted it with a sleep(1000) and I get the same random error... The problem is somewhere else. Still investigating...

Share this post


Link to post
3 minutes ago, Lars Fosdal said:

Do you .Free or FreeAndNil?

It depends... I use both

 

3 minutes ago, Lars Fosdal said:

Are you using EurekaLog or MadExcept?

I'm using madExcept 

Share this post


Link to post

I use EL, so I can't really opinionate on MadExcept.  It is very rare that it gives me no clue to the callstack for exceptions caused by dangling pointers, but when desperate, I've turned to using a FreeAndNil overload to set the pointers to a recognizable value, $DEAD0001 and so forth, and logging the line where I set the respective ptr values to at least find a hint to the context that is trying to use it. Problems like these can be a pain to find.

 

Another alternative would be to try with regular threads to see if the problem persists - if it doesn't, it might be that you can attribute it to something OTL specific?

 

 

  • Like 1
  • Thanks 1

Share this post


Link to post

I spent some time to deep analize the MadExcept callstack and I discovered that the thread in exception was created by another thread not even executing (I can't find his "father" in the thread list reported by madExcept).

Now I've rearranged same things in the steps involved in the app terminating phase to avoid this; I've also moved the IOmniTimedTask instance as a global variable to avoid strange dependencies. Now I cannot reproduce the error.

 

So OTL seems working fine as usual!  It's always a mess working with threads!

Share this post


Link to post

Usually a mess we create ourselves 🙂

It may be that the dead thread raising the exception was trying to use an already disposed reference in it's final moments.

  • Like 1
  • Thanks 1

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
×