Search code examples
c++multithreadingasynchronousmfcstdasync

Callback function error in std::async call


Using this code sample to add multithreading callback mechanism for the following code using std::function and std::bind.

void MyClass::afterCompleteCallback(string stsstr)
{
     CString strResult;
     strResult.Format(L"You received: %s", stsstr); //expected "My Output 1"
     GetDlgItem(IDC_STATIC)->SetWindowTextW(strResult);
}

void MyClass::StartMyThread()
{
    auto callback = std::bind(&MyClass::afterCompleteCallback, this, std::placeholders::_1);
    string _data = "My Input 1"
    _aStatus = std::async(std::launch::async, longRunningFunction(callback), data);
}


void MyClass::OnBnClickedButton1()
{
    StartMyThread();
}

I am modifying the longRunningFunction(callback) with

auto _aStatus = std::async(std::launch::async, longRunningFunction(callback), data);

but getting the error no instance of overloaded function matches the argument list error.

My end goal is to pass some str data to thread OnButtonClick() event and get a str result from the thread via callback and update in the MFC TextEdit control. How can I achieve this?


Solution

  • A safe way to accomplish this would be to use sending message(s) from your thread, something like:

    void MyClass::longRunningFunction(callback, HWND hWnd)
    {
    //  longRunning_task
        ::PostMessage(hWnd, WMU_NOTIFYTHREAD, WMU_JOBDONE, 0/*items_received*/);
    }
    

    and then:

    // CMyDialog implementation
    
        BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
            //{{AFX_MSG_MAP(CMyDialog)
            //}}AFX_MSG_MAP
            ON_MESSAGE(WMU_NOTIFYTHREADUPDATE, &CMyDialog::OnNotifyThread)
        END_MESSAGE_MAP()
    

    and

    LRESULT CMyDialog::OnNotifyThread(WPARAM wParam, LPARAM lParam)
    {
        switch (wParam)
        {
        case WMU_JOBDONE:
            CString sText{};
            sText.format(_T("You received: %d"), lParam);
            GetDlgItem(IDC_STATIC)->SetWindowTextW(sText);
            break;
        }
    
        return 1;
    }