Actually using either Tick or a timer on your main thread is what you want to do. In my case I had a thread that was called by the game state and would constantly update as long as the match was in session so I create a variable
bool threadFinished;
Then in the thread I created a reference to that variable
bool *threadFinished
When starting that thread I pass that variable to the singleton.
MyThread::Init(&threadFinished, &data);
On my thread when the work is done, I set the threadFinished reference to true and it sets it on the game thread (since you passed a reference to it)
This polling approach is what I used and it cut my Game thread time in half.