VS2010窗体多线程问题。
创建了窗体Form1,上有控件button2,在button2_click时事件中使用Thread类创建了一个新线程。调用语句:Thread^tth=gcnewThrea...
创建了窗体Form1,上有控件button2, 在button2_click时事件中使用Thread类创建了一个新线程。
调用语句:
Thread^ tth=gcnew Thread(gcnew ThreadStart(this, do_server));
do_server是Form1中一个非静态成员函数,该函数要访问Form1中的非静态成员。
但在调试时,我进入到do_server()中看Form1对象的this指针,却发现对象没有创建,(我抱证此时还未调用对象的析构函数)所以访问对象的所有控件是都会出错。
不知何故,望高手帮助解答。
我使用的是C++.NET。
do_server不管是使用静态函数还是非静态函数,都存在这个问题。而且,我生成过一个较小的测试工程,在那个工程里do_server没有做仍何多余的事,可是问题还是没有解决。 展开
调用语句:
Thread^ tth=gcnew Thread(gcnew ThreadStart(this, do_server));
do_server是Form1中一个非静态成员函数,该函数要访问Form1中的非静态成员。
但在调试时,我进入到do_server()中看Form1对象的this指针,却发现对象没有创建,(我抱证此时还未调用对象的析构函数)所以访问对象的所有控件是都会出错。
不知何故,望高手帮助解答。
我使用的是C++.NET。
do_server不管是使用静态函数还是非静态函数,都存在这个问题。而且,我生成过一个较小的测试工程,在那个工程里do_server没有做仍何多余的事,可是问题还是没有解决。 展开
2个回答
展开全部
经测试,没有再现你的错误,请贴出完整源代码,供本人测试。
另外,你 gcnew ThreadStart(this, do_server) 中的 do_server 实参写错了,应该是:&窗体类名::do_server。
以下代码测试,完全正常。
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
Control::CheckForIllegalCrossThreadCalls = false; // 取消线程安全检查
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Thread^ th = gcnew Thread(gcnew ThreadStart(this, &Form1::do_server));
th->Start();
}
private: System::Void do_server()
{
this->button1->Text = "abcdefg"; // 成功访问了 button1 控件,并设置了 Text 属性
MessageBox::Show("AAAAAAAAAAAAAAA");
}
另外,你 gcnew ThreadStart(this, do_server) 中的 do_server 实参写错了,应该是:&窗体类名::do_server。
以下代码测试,完全正常。
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
Control::CheckForIllegalCrossThreadCalls = false; // 取消线程安全检查
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Thread^ th = gcnew Thread(gcnew ThreadStart(this, &Form1::do_server));
th->Start();
}
private: System::Void do_server()
{
this->button1->Text = "abcdefg"; // 成功访问了 button1 控件,并设置了 Text 属性
MessageBox::Show("AAAAAAAAAAAAAAA");
}
追问
Control::CheckForIllegalCrossThreadCalls = false;
这句话是必须加的吧。
追答
这句话并不是必须加的。
正常情况下,涉及到影响界面的代码应该由 UI 线程执行,而不是工作线程。
特别是操作 COM 控件时,如果用工作线程更改控件状态,会导致非法操作(包括把 CheckForIllegalCrossThreadCalls 设置 false 也会)。
在没有设置 CheckForIllegalCrossThreadCalls 为 false 时(默认 true),运行时环境会检测上述情况。
工作线程更改界面的问题,请参考 Control::Invoke 方法的 MSDN 解释。
所有 Windows 控件均从 Control 类继承,因此都有 Invoke 方法,所以异步更改控件状态,请通过调用控件实例的 Invoke 方法实现。
注1:Invoke 机制,就是将委托指向的方法,交给 UI 线程执行。
注2:Invoke 内部的实现,是工作线程调用 Win32 API 的 SendMessage 发送消息给 UI 线程(即:发送给窗口)并等待答复,UI 线程收到消息后根据消息的参数,执行相应的委托。
例子 MSDN 上有,如果安装了 MSDN 请点击 ms-help://MS.MSDNQTR.v90.chs/fxref_system.windows.forms/html/71280002-4fdd-b084-d223-9167cfc0031a.htm
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |