FileChooser dialogue persists on screen

I have a program which, when a button is clicked, shows a FileChooser (OSX native) and then spends many seconds processing the selected file. This all works except that the FileChooser window persists on the screen covering up the main window. It seems to persist until the button clicked method returns. Is there a way of modifying this behaviour so that it goes away as soon as the file is chosen?
I tried running the lengthy task on a separate thread but it appears such a thread may no call repaint() (get a JUCE assert) and thus, to make this work I would seem to need a
proper way for the second thread to invoke this. Any help appreciated.

You can use juce::MessageManagerLock to be able to call such methods from non-message threads:

void run() override
{
    while (! threadhShouldExit())
    {
        const juce::MessageManagerLock mml {this};

        if (mml.isLocked())
            repaint();
    }
}

Or, simply trigger the repaint asynchronously:

void run() override
{
    juce::MessageManager::runAsync ([this] () {
        repaint();
    });
}

You may also be interested in ThreadWithProgressWindow.

Alternatively, if you just want to do everything on the message thread and not have to mess around making new threads, you could just do the work asynchronously when the file is chosen using either juce::AsyncUpdater or juce::MessageManager::callAsync.

I think this goes in the wrong direction.
You can destroy the FileChooser in the code that is executed when the file is selected. But chances are the actual destruction of the native FileChooser happens asynchronously. That means you would have to pump the message loop manually (last resort) or indeed trigger the lengthy task using a juce::ThreadPoolJob (preferred). That makes the method return immediately after the job is scheduled and makes the UI responsive again.

Triggering repaint() won’t help, since the actual painting is only scheduled and you are back to square one.
On the other hand the destruction of the FileChooser will automatically mark the region as dirty and it will repaint automatically.

I’ve been experimenting. I think destroying the file chooser does NOT immediately remove it from the screen. I enclosed its declaration in { } and it made no difference. I would have hoped that destruction would remove it but it does not (not on OSX that is). What seems to remove it is the button-press handling code that creates the file chooser returning control to the system. I have avoided the problem by having the lengthy task run on a separate thread and signalling completion with callFunctionOnMessageThread. I am going to try AsyncUpdater as that seems to be neater. Thanks for the help, it got me going when I was stuck.

I am now using AsyncUpdater. This is a much neater solution than callFunctionOnMessageThread… all type safe and no casting of void* pointers etc. Problem solved. Thanks