5YrsLaterDBA
5YrsLaterDBA

Reputation: 34820

Why still Cross-thread operation not valid error with delegate Invoke?

I have a VC++2008 Form Application with some unmanaged socket communication code. I want to display the communication message on the form. In order to avoid above error, I have added delegate method and used the Invoke call. But I still get above error. Anybody can help me correct my code?

This is the Form1 header file:

#pragma once

#include "SocketClientMgr.h"
class SocketClientMgr;

namespace SocketClientFormApp {

    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {
            InitializeComponent();
            updateHandler = gcnew ProgressHandler(this, &SocketClientFormApp::Form1::updateLogMsg);
        }
    protected:
        ~Form1()
        {
        }
    private:

#pragma region Windows Form Designer generated code

        void InitializeComponent(void)
        {
        }
#pragma endregion

///////////////////////////////////

    private: delegate void ProgressHandler(String^ msg);
    static ProgressHandler^ updateHandler;

    public: void appendMsg(String^ msg);
    public: void updateLogMsg(String^ msg);
};
}

This is the Form1 cpp file:

#include "stdafx.h"
#include "SocketClientForm.h"

using namespace SocketClientFormApp;

void Form1::appendMsg(String^ msg)
{
    updateHandler->Invoke(msg);
}

void Form1::updateLogMsg(String^ msg)
{
    msgDisplayBox->AppendText(msg);
}

The appendMsg() method will be called from another class in another thread.

EIDT:

static ProgressHandler^ updateHandler; static should not be there and it should be private

error happened at updateLogMsg() enter image description here

Upvotes: 1

Views: 447

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064104

A delegate's Invoke(args) just runs on the current thread; you need someControlInstance.Invoke(delegate, args) (quite commonly, "this.Invoke(...)"), which uses the message loop to transfer the delegate call to the UI thread, avoiding the cross-thread issue.

Equally;

  • Delegate.BeginInvoke uses the ThreadPool
  • Control.BeginInvoke uses te message-loop

Upvotes: 2

Related Questions