Well, the process can probably stall, without actually failing, for a fairly long period.
That is why some functions allow specifying a timeout so if what you want to do, such as connect to a server, doesn't happen in a reasonable period, it will time out and return to you with an error code.

In other cases, I might want to allow it to wait as long as it will to do something, but usually have a "GUI Timer" that runs periodically to update various status indicators and update the form, because in some of my uses, the form has a number of tab pages to show different state data for different connections, so I don't update all the controls on all the pages all the time, just the current showing page for the currently selected interface. And data may be coming in at a faster rate than I want to update the display, so the display updates are governed by the GUI timer, and the state data for all interfaces is updated at whatever rate it is received.

In that scenario, the background thread can set a variable to indicate what it is trying to do (e.g. connect to the server, or waiting for a response), and also set a "watchdog" integer variable to some desired countdown value at the start of the action.
For instance, if my GUI timer is running at 10hz, and the background thread is trying to connect to the server, and I want to allow for around a 1/2 second for that to happen, the background thread can set the "watchdog" variable to 5, and start trying to connect. The GUI timer would see that we're in a "trying to connect state" and decrement the "watchdog" variable each pass, and if it reaches zero, flag a connection error.

I don't have time to check, but in the case of doing a TCP connect, there is probably already a timeout value you can specify, so you don't have to go the "watchdog" route for that phase if you don't want to.