Thread Confusion Question :)

Hello :wink:

Ok I am having a moment of confusion with implementing a thread with sockets in it. The implementing part was easy, but the details are confusing me as I watch the IDE debugger with it. This code all works, but I am wondering if I am missing any small details regarding accessing the Thread later on in the main thread.

The main purpose of this EVIP Thread is to run the ServerSockets outside of the Main thread. So naturally it will run the whole time the main thread (App) runs.

This is a Desktop App. --> GrandCentralSocketsThread.Run --> GrandCentralSockets_Initialize(Code Below)

// GrandCentralSockets_Initialize Method //
  GrandCentralSocket = New GrandCentralSocket_Class
  GrandCentralSocket.MaximumSocketsConnected =20
  GrandCentralSocket.MinimumSocketsAvailable = 20
  GrandCentralSocket.Port = 8411

Then GrandCentralSockets.Run --> (Code below)

  EVIP_Socket= New EVIP
  EVIP_Socket.ICPMonitor_Socket_InitialEntry(PreviousID,"Listening for connection")
  App.GrandCentralSocket_Thread.EVIP_Listening_Socket_Pool_Array.Append EVIP_Socket
  PreviousID = PreviousID + 1
  Return EVIP_Socket

Ok so this works and this is a out of band management protocol subclassed from TCPSockets(Controlled by Server Sockets).

My question … When I look at the debugger it shows the GrandCentralStation Thread in State 4(not running) as I understand it finished “initializing” the server sockets. However I am always running methods on the EVIP Subclass all under the Thread and it still works even though the thread is not running.

For example through out the main thread I call methods that are inside of this thread/socket hierarchy and it works fine still even though when I pause the debugger it shows as State 4.

So naturally I am wondering … Ok – If Status of thread is 4 (not running) then how are we accepting and processing all of these new connections? :slight_smile:

Hopefully this makes sense and thank you very much.

Do I just need to keep that Thread alive for the duration of the app? ie. in the Thread.Run event

SystemLogging.SystemErrorLog(“EVIP Thread Sleep”)

? Thanks :slight_smile:

A couple of thoughts:

  1. Code runs in the thread that called it, regardless of where it is defined.
  2. Socket events always run in the main thread.

Hate to say it, but your thread isn’t really doing anything for you. All it really does that could take appreciable time is call ICPMonitor_Socket_InitialEntry. If that does indeed take a long time to complete, then the thread is useful. Otherwise, it doesn’t help at all.

To unpack 1), above, if I create a Thread subclass and define a method in it and then call that method from a pushbutton action event, the code in that method runs in the main thread, even though it is “part of” a thread class definition. It doesn’t matter where the code is defined, it runs in the thread that called it.

Thanks Tim. I will try that! :slight_smile:

When you get a pause in the debugger everything is “stopped” - including the thread scheduler etc :stuck_out_tongue:
You’d probably have to log states from the actual threads to see that they run , sleep etc since the debugger pauses execution of EVERYTHING in the target app

If I put a breakpoint in a thread, the debugger reports the state as 0 (Running). In Mike’s case, the thread really had completed (it did practically nothing) and everything was still being done in the main thread.

It certainly does look that way based on a closer read of his original post

Thanks guys! I will have to shift my thinking and keep the server sockets in the main thread while moving some of the GUI stuff over to the thread.

I assume threads only running in the main thread is the same on a Console app also?

Thank you again.

Assuming you mean “events” only running in the main thread, yes it is the same in a console app. Not sure what you mean by “moving some of the GUI stuff over to the thread,” though. You can’t update the GUI from a thread.

What are you trying to accomplish? Keep the GUI responsive in the face of multiple sockets? If so, make sure you keep your DataAvailable code short. If it needs to do something that takes time, that is where you use a thread. Move the long process into a thread subclass and Run the thread in DataAvailable.

Tim thank you and I understand now what you are explaining. :slight_smile: Thank you again.