If the worker thread is running blocking code which is presumably why you pushed it to a worker thread in the first place, then it is blocked and it cannot communicate with you directly since it would have to receive a message from you and send a response for you to communicate with it, but if it's blocked doing something else, then it isn't processing messages so you can't talk to it until it's done.
Things you could do:
Have worker thread tell you when it started and when its done
When the function starts running, it sends a message to the main thread. The main thread gets that message and stores that state. When the function completes, it sends a message to the main thread that is has completed. The main thread will receive that and can update the state.
So, as long as the worker thread follows that logic reliably, then at any time, the main thread can just consult the state it has to know whether the worker thread last told it was running or done.
Test message processing responsiveness of the worker thread
Another option would be to send a message to the worker thread with some sort of uniqueID in it and note the time you sent the message. Then, the worker thread (when it is free to process that message) will respond to it and return back the same uniqueID. From the main thread, you can assume that if you don't get a quick response from the message you sent to the worker, then it must have been busy. You have to use the uniqueID because the response will come back sometime in the future and you have to know which responses to pay attention to and which might be old. This is basically just a test to see whether the worker thread is responding to messages quickly - thus indicating that it's not being blocked by some blocking operation that is currently running.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…