Problems with Threads, Locks in my first Project

Hey i’m new to Juce / audio development

I’m currently working on my first project (vst) a Sampler / Synth and i want to implement threading for sample loading & pre-processing of the sample.
while loading the sample the UI thread should be locked while my LevelMeters will still update (own thread?) if possible if not i want to skip sections while the thread is running using the “isThreadRunning()” function with an “if” and notifying the UI thread that the loading sample thread has finished and the UI can repaint.

here is what i have so far (of course highly reduced)
i have tried the last two 2 days alot of diffrent things but nothing seems to work probably
so im looking forwad to any kind of advice

PluginEditor.cpp

SampleBasedSynthAudioProcessorEditor::SampleBasedSynthAudioProcessorEditor (SampleBasedSynthAudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p), Thread("UI")
{
    addAndMakeVisible(levelMeterLeft);
    addAndMakeVisible(levelMeterRight);

    startTimerHz(24);
}


void SampleBasedSynthAudioProcessorEditor::paint (juce::Graphics& g)
{
    if (!loadedSampleOne) { g.drawFittedText("drag&drop sample here!", sampleOneBackground.getSmallestIntegerContainer(), juce::Justification::centred, 1); }

    if (loadedSampleOne) // && !sampleLoader.isThreadRunning()
    {
        drawWaveform();
    }
}


bool SampleBasedSynthAudioProcessorEditor::isInterestedInFileDrag(const juce::StringArray& files)
{
    for (auto file : files)
    {
        if (file.contains(".wav") || file.contains(".mp3") || file.contains(".aif"))
        {
            return true;
        }
    }
    return false;
}


void SampleBasedSynthAudioProcessorEditor::filesDropped(const juce::StringArray& files, int x, int y)
{
    for (auto file : files)
    {
        if (isInterestedInFileDrag(file))
        {
            if (zoneOne.contains(x, y))
            {
                sampleLoader.loadSample(file, audioProcessor.getMySampleBufferOne(), audioProcessor.getSynth());
                loadedSampleOne = true;
            }
        }
    }
    while (sampleLoader.isThreadRunning())
    {
        DBG("loading...");
        wait(250);
    }
    repaint();
}


void SampleBasedSynthAudioProcessorEditor::timerCallback()
{
    levelMeterLeft.setLevel(audioProcessor.getRmsValueLeft());
    levelMeterRight.setLevel(audioProcessor.getRmsValueRight());
    levelMeterLeft.repaint();
    levelMeterRight.repaint();
}

SampleLoader.h

class SampleLoader : public juce::Thread
{
public:
    SampleLoader() : juce::Thread("Load Sample")
    {
        formatManger.registerBasicFormats();
    }

    ~SampleLoader()
    {
        formatReader = nullptr;
        formatWriter = nullptr;
    }

    void loadSample(juce::String& p, juce::AudioBuffer<float>& b, juce::Synthesiser& s)
    {
        setPath(p);
        setBuffer(b);
        setSampler(s);
        startThread(Priority::normal);  
    }

    void setPath(juce::String& p) { file = juce::File(p); }

    void setBuffer(juce::AudioBuffer<float>& b) { buffer.reset(&b); }

    void setSampler(juce::Synthesiser& s) { sampler.reset(&s); }
   
private:

    void run() override
    {
        formatReader.reset(formatManger.createReaderFor(file));

        auto sampleLength = static_cast<int>(formatReader->lengthInSamples);

        buffer->setSize(2, sampleLength);
        formatReader->read(buffer.get(), 0, sampleLength, 0, true, true);

        //TO-DO pre-processing

        file = ("D:/test.wav");
        file.deleteFile();
        

        writer.reset(wavFormat.createWriterFor(new juce::FileOutputStream(file),
            44100,
            buffer->getNumChannels(),
            24,
            {},
            0));

        if (writer != nullptr)
            writer->writeFromAudioSampleBuffer(*buffer.get(), 0, buffer->getNumSamples());


        juce::BigInteger range;
        range.setRange(0, 128, true);

        formatReader.reset(formatManger.createReaderFor(file)); // <- not working
        formatReader->read(buffer.get(), 0, sampleLength, 0, true, true);

        sampler->clearSounds();
        sampler->addSound(new juce::SamplerSound("Sample", *formatReader, range, 60, 0.01, 0.1, 16.0));
    }

    juce::File file;
    std::unique_ptr<juce::AudioBuffer<float>> buffer;
    std::unique_ptr<juce::Synthesiser> sampler;

    juce::AudioFormatManager formatManger;
    std::unique_ptr<juce::AudioFormatReader> formatReader { nullptr };

    juce::WavAudioFormat wavFormat;
    std::unique_ptr<juce::AudioFormatWriter> writer;

};

I also have 2 other problems with my sampleLoader class
1: reading out the newly created file will not work the reader read function will always result in an empty buffer and when playing a note it crashes
2: The second Time when loading a sample the programm crashes when setBuffer(b); is been called

Error message:

HEAP[AudioPluginHost.exe]: Invalid address specified to RtlValidateHeap( 000001FE440C0000, 000001FE46176548 )
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in AudioPluginHost.exe.

delete_scalar.cpp

_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
    #ifdef _DEBUG
    _free_dbg(block, _UNKNOWN_BLOCK);
    #else
    free(block);
    #endif
}

Okay i was able to fix the 2 bucks below just had to handle the release and reset of some reader / writer and the buffer, synth

Threading is working also. Now i’m inheriting the ActionListener on the editor
and my SampleLoader inherited the ActionBroadcaster
so i can now send a message thru the broadcaster and my UI thread gets a callback and performs the repaint task