mercredi 12 janvier 2022

Can't save CDocument in a worker thread -- object is destroyed from memory before thread starts

Overview

I need to save a CDocument in a background worker thread. There is a point in our MFC application which prompts the user to save before continuing. Normally, they are able to continue without saving, and there is no problem. However, occasionally, we need that document later in the process, so if the user clicks "No", we want to save a temp version of the file in the background without making the user wait for the save to continue.

Problem

When I launch AfxBeginThread(SaveDocumentThread, &threadInput) the &threadinput has been cleared from memory before the SaveDocumentThread starts.

Code

BOOL SPackagerDoc::OnSaveDocument( IN LPCTSTR lpszPathName)
{
    ProcessDocumentThreadInput threadInput(this, lpszPathName);
    
    // Temp Save Mode
    if (m_bTempMode)
    {
        m_TempSaveThread = AfxBeginThread(SaveDocumentThread, &threadInput);
        // This fixes the problem, but is considered unstable
        // if (m_TempSaveThread->m_hThread)
        //        WaitForSingleObject(m_TempSaveThread->m_hThread, 500);
        return TRUE;
    }

    // Normal save mode
    SFileLoadingDialog loadingDialog(SFileLoadingDialog::SAVE, lpszPathName, SaveDocumentThread, &threadInput);
    BOOL result = (BOOL)loadingDialog.DoModal();

    return result;
} 

StUInt32 SPackagerDoc::SaveDocumentThread(IN StVoid* pParam)
{
    ProcessDocumentThreadInput* input = (ProcessDocumentThreadInput*)pParam;
    ASSERT_NOT_NULL(input);
    ASSERT_NOT_NULL(input->pPackager);
    ASSERT_NOT_NULL(input->pszPathName);

    CString path_name(input->pszPathName);

    BOOL result = input->pPackager->SPackagerDocBase::OnSaveDocument(path_name);
    return result;
}

If I uncommend WaitForSingleObject(..., 500); then the thread starts, all the information is present, and there are no errors. But if I remove those lines then in SaveDocumentThread input is NULL and all data is zeros or garbage.

Is there a way to ensure the SaveDocumentThread has started before moving on. IE, wait for thread to start, but not for a specified amount of time (500 ms). It may be that 500 ms is not a sufficient wait time on some other computers.

Is there an "official" way to do this?

Aucun commentaire:

Enregistrer un commentaire