将回调函数传递给C ++ / CLI中的线程
一些上下文:我知道基本的C ++。 我第一次尝试使用C ++ / CLI在Visual Studio中创建GUI应用程序。 但是,我无法在网上找到关于后者的很多答案。
我有类: MyForm
,与Windows窗体和OtherClass
相对应的主类。 MyForm
有一个类型为OtherClass
的对象作为成员。 MyForm
一个函数,在这个例子中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
以便在foo
运行时使用foo
值更新UI。
什么是最好的方法来做到这一点? 因为CLI,简单地传递函数指针不起作用。
我有它的工作。 但是,正如@Hans Passant所指出的,这非常类似于BackgroundWorker
的行为。 无论如何,下面是没有使用BackgroundWorker
问题的答案。 虽然感觉不太干净。
正如@ orhtej2指出的那样, delegate
是需要的。 对于上面的两个头文件来识别它,我不得不在stdafx.h
声明委托(如这里所建议的),例如像这样:
delegate void aFancyDelegate(System::String^);
然后,我将这样一个委托传递给了OtherClass的构造函数,所以MyForm
的对象初始化行从
o = gcnew OtherClass;
至
aFancyDelegate^ del = gcnew aFancyDelegate(this, &MyForm::callbackFunction);
o = gcnew OtherClass(del);
。
最后,为了能够从callbackFunction
更新UI元素,即使它是从另一个线程调用的,它也必须包含这样的内容,正如本答案中的建议:
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/27811.html