When the TCP socket is receiving data, it blocks the execution of the Timer Action

Here is the scenario:

  • I have a socket server that instantiates up to 40 TCPSockets.
  • I have a timer (Timer1) with run mode set to “multiple” and period set to 1 second (1000).

When the 40 TCPSockets are receiving data, the timer is ignored, even though it is supposed to trigger every second.

If I disconnect all the TCPSockets, the timer starts working again;
has anyone encountered something similar?

W11 Pro, Xojo 2026R2 (67638)

basicaly you can say if xojo is inside of a method in blocks the main loop from continue.

I logged this enhancement to improve TCP sockets:

https://tracker.xojo.com/xojoinc/xojo/-/issues/81087

1 Like

I don’t quite follow: are you saying that if one of the TCP sockets is receiving data—triggering the dataAvailable event—it won’t process any other code until that execution finishes?
So, would 40 TCP sockets receiving data continuously block all other application activity, including timers?

Unfortunately, the socket and timer events are all running on the main thread which means only one method can run at a time.

You need to make the DataAvailable events do as little as possible - ie: add the incoming data to a buffer and process it via a thread.

The enhancement which I referred to in my previous post is for sockets to use preemptive threads which would free the main thread to allow the timer to operate correctly.

1 Like

you could also run a thread and compare a datetime and then do what you need to do.
and with Preemptive Threads it could run at different cpu core too.

the question is what is your timer intent to do.

Thank you all.

i think is that the best approach is create 2 apps, one for listeners and other to elaborate buffer (Buffer = same local sqllite db for listener app end for queque elaborator app ) , the second app (queque elaborator) in not impatted from the tcpsocket of the firs app and can use premptive threads and his timer

DataAvailable will be fired on the main thread, so reading the data might block it.

Have you tried using a Thread for reading the data? Once DataAvailable fires, start the thread and read from the socket.

1 Like

thank you Ricardo, you suggesting pass the buffer readed from tcpSocket to a thread ?
or manage the socket from the called thread ?

I mean, instead of calling .ReadAll directly from the DataAvailable event, call this method from a Thread (it doesn’t need to be a Preemptive Thread, it’s just I/O blocking)

1 Like

I would expect ReadAll to be very fast (it’s just a memory copy) so it’s probably fine to do that in the DataAvailable event.

I would guess it’s the processing you do on that data which is the actual slowdown.

If I were you, I’d do some targeted logging to figure out what’s taking time:

Event MySocket.DataAvailable
   // read data
   var t0,dt as double 
   t0 = system.microseconds
   var s as string = me.ReadAll
   dt = (system.microseconds - t0)/1000
   system.debugLog ("ReadAll took " + dt.ToString + " msec")

   // process data
   t0 = system.microseconds
   [ ... insert your processing code here...]
   dt = (system.microseconds - t0)/1000
   system.debugLog ("Process took " + dt.ToString + " msec")

With that info, you could decide which operation(s) to move to a thread.

2 Likes

Excuse me Ricardo ..
Just out of curiosity: if I run the same projec which currently runs on Windows Server 2019 (or Windows 10/11 Pro in debug mode ) on Linux, will I get better results?
In other words, on Linux (using the corresponding Linux executable), does the constant reception activity from 30/40 TCP sockets impact the main thread in the same way blocking timer code execution or are they handled more effectively?

Be VERY CAREFUL. If you do it this way, another DataAvailable event may fire on that same socket and you could end up processing the same data twice.

My suggestion is that you subclass TCPSocket and add a buffer() as string property and they only thing you do in DataAvailable is

Buffer.Add(me.readAll)

Use a timer to look to see if buffer.count > 0 and use that to trigger your thread work.

3 Likes

Thank you Greg
but if i have 30 or 40 TCP sockets and these recieve a large amount of data simultaneously, I believe the main thread will remain busy and the timer action won’t be executed

i think that this is the same if i sublcass tcp socket or if i use thread to read data from tcpsocket

im curios if this is limit of using tcpSocket on windows and non if i use this on linux or if it is limit of tcp socket component on all platforms

I’m 99.9999% sure that it will unless Xojo has changed something major recently. That’s how I did it in Xojo web framework v2.

1 Like

It’ll be all platforms. It’s just about how the underlying sockets work. I just ran into this in my own tcp socket implementation this week.

1 Like