Passing callback function to thread in C++/CLI

Some context: I know basic C++. For the first time, I'm trying to create GUI application in Visual Studio using C++/CLI. However, I can't find much answers online about the latter.

I've got to classes: MyForm , the main class corresponding to a Windows Form, and OtherClass . MyForm has an object of type OtherClass as a member. A function of MyForm , in this example myButton_Click , initializes this object and calls one of its function in a thread:

using namespace System::Threading;

ref class MyForm;
ref class OtherClass;

public ref class MyForm : public System::Windows::Forms::Form {
    public:

    //...

    private:
        OtherClass^ o;

        System::Void myButton_Click(System::Object^  sender, System::EventArgs^  e) {

             //When the button is clicked, start a thread with o->foo
             o = gcnew OtherClass;
             Thread^ testThread = gcnew Thread(gcnew ThreadStart(o, &OtherClass::foo));
             newThread->Start();

        }



};

ref class OtherClass {
    public:
        void foo() {
            //Do some work;
        }
};

This seems to be working, so far. What I want is to pass some kind of callback function from MyClass to o->foo to update the UI with values from foo while it's running.

What's the best way to do this? Simply passing function pointers doesn't work because of CLI.


I've got it working. However, as pointed out by @Hans Passant, this is pretty much mimicking the behavior of a BackgroundWorker . Anyway, below is the answer to the top question, without using a BackgroundWorker . It feels not very clean, though.


As pointed by @orhtej2, a delegate is what's needed. For both of the above header files to recognize it, I had to declare the delegate in stdafx.h (as suggested here), for example like this:

delegate void aFancyDelegate(System::String^);

I then passed such a delegate to the constructor of OtherClass, so the object initialization line in MyForm changed from

o = gcnew OtherClass;

to

aFancyDelegate^ del = gcnew aFancyDelegate(this, &MyForm::callbackFunction);
o = gcnew OtherClass(del);

.

Lastly, to be able to update UI elements from callbackFunction , even if it was called from another thread, it had to include something like this, as suggested in this answer:

void callbackFunction(String^ msg) {

            //Make sure were editing from the right thread
            if (this->txtBox_Log->InvokeRequired) {
                aFancyDelegate^ d =
                    gcnew aFancyDelegate(this, &MyForm::callbackFunction);
                this->Invoke(d, gcnew array<Object^> { msg });
                return;
            }

            //Update the UI and stuff here.
            //...
        }
链接地址: http://www.djcxy.com/p/27812.html

上一篇: 在.NET WinForms中创建一个自定义菜单

下一篇: 将回调函数传递给C ++ / CLI中的线程