1

I am using OTL for the first time and I was trying to use the Async/Await abstraction.

Now, I created a small program just to see what will happen. It's just a button and it calls this procedure.

procedure TForm2.Button1Click(Sender: TObject);
var i : integer;
begin
Button1.enabled := false; //Only for second try

for i := 0 to 100 do
begin

Async(
  procedure begin
    sleep(5000);
end).
Await(
  procedure begin

  //First Try - Button1.Enabled := true;

  //Second Try - showmessage('finished')

  end
);

Button1.enabled := true; //Only for the second try.

  end;
end; 

First Try

For this it works fine the first time, disable the button, sleep for the asyncs and then enable it back.

But the second time I click the button, it is disabled but never gets enabled again.

Second Try

This time I wanted to show a message x100 times and it works the first time aswell, but when I call the procedure again I get the following error TOminCommunicationEndpoint.Send: Queue is full

Can someone who has used this library explain to me, why am I getting this error? And if it is related to the problem with the first try?

Diego Rueda
  • 2,226
  • 4
  • 21
  • 41
  • When you run this code under the debugger, an exception is raised which tells you the problem. You should get into the habit of using the tools provided. The debugger is useful. – David Heffernan Apr 08 '14 at 08:13

1 Answers1

2

It seems you are hitting an internal limitation of OTL.

Each call to Async-Await starts a new thread and returns immediately. When the loop is done you end up with 100 threads, each waiting 5 seconds before executing the Await code.

AFAIK, there is a limitation of 60 concurrent threads in OTL when using the threadpool.

Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130
  • This cannot be true. If there were N hidden locals, one per loop iteration, then the stack frame size would not be known at compile time. There must be a single hidden local. – David Heffernan Apr 08 '14 at 06:53
  • @DavidHeffernan, you are right. As it seems still due to a limitation in OTL I reworked my answer. – Uwe Raabe Apr 08 '14 at 07:22
  • 1
    60 threads limit must be customisable. I have clients with machines with mores cores than that. I suppose that's a question for Primoz. – David Heffernan Apr 08 '14 at 07:24
  • 1
    @DavidHeffernan, sometimes the number of cores is not the limiting factor in multithreading. You can easily need more threads than cores if threads are waiting for I/O. I guess the limiting factor is either memory or how many threads per process the OS permits. – LU RD Apr 08 '14 at 07:50
  • 1
    @LURD true. No matter, 60 is too low. – David Heffernan Apr 08 '14 at 07:56
  • 2
    http://stackoverflow.com/questions/13458029/why-is-omnithreadlibrary-limited-to-60-threads-when-nets-limit-is-32768 – Sir Rufo Apr 08 '14 at 07:56
  • @LURD 60 threads is just way too low. How can this limitation be removed? `.NET` has no such limit and thats Managed code.. – user3060326 Apr 08 '14 at 09:23
  • @DavidHeffernan There are 4 Socket AMD motherboards with 64 cores. Intel has even 8 socket motherboards. It seems `OTL` is really behind on this one. – user3060326 Apr 08 '14 at 09:41
  • 2
    @user3060326 Yes it is. It needs to reimplement this functionality using IOCP, I believe. – David Heffernan Apr 08 '14 at 09:48
  • @user3060326, a Delphi example of thread pooling using IOCP is written by Eric Grange, [Using IOCP for Worker Threads](http://www.delphitools.info/2013/09/03/using-iocp-for-worker-threads/). – LU RD Apr 08 '14 at 15:15
  • @LURD But sadly thats not `OTL` :) – user3060326 Apr 08 '14 at 15:20
  • As David said, that is up to @gabr to answer. – LU RD Apr 08 '14 at 15:26