代码之家  ›  专栏  ›  技术社区  ›  Fii

在C++/CLI中将回调函数传递给线程

  •  0
  • Fii  · 技术社区  · 7 年前

    我有两门课: MyForm ,对应于Windows窗体的主类,以及 OtherClass . 我的表单 具有类型为的对象 其他类别 作为成员。函数 ,在本例中 myButton_Click ,初始化此对象并在线程中调用其函数之一:

    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;
            }
    };
    

    从传递某种回调函数 MyClass o->foo 使用来自的值更新UI foo 当它运行时。

    最好的方法是什么?由于CLI的原因,简单地传递函数指针不起作用。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Fii    7 年前

    我已经开始工作了。然而,正如@Hans Passant所指出的,这在很大程度上是在模仿 BackgroundWorker . 不管怎样,下面是第一个问题的答案,不使用 后台工作人员


    正如@orhtej2所指出的, a delegate is what's needed . 为了使上述两个头文件都能识别它,我必须在中声明委托 stdafx.h (根据建议 here ),例如:

    delegate void aFancyDelegate(System::String^);
    

    MyForm 更改自

    o = gcnew OtherClass;
    

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

    .

    最后,能够从 callbackFunction ,即使它是从另一个线程调用的,它也必须包括这样的内容,如中所示 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.
                //...
            }