有关线程问题,路过请看看。 ( 积分: 100 )

  • 主题发起人 主题发起人 chenzhu
  • 开始时间 开始时间
C

chenzhu

Unregistered / Unconfirmed
GUEST, unregistred user!
有两个窗体Form1和Form2,还有一个线程对象MyThread:
在Form1有一个按钮,实现功能如下:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyThread *pMyThread = new MyThread(true);
pMyThread->Resume();
}
在线程对象MyThread实现功能如下:
void __fastcall MyThread::Execute()
{
TForm2 *pForm2 = new TForm2(Application);
pForm2->ShowModal();
}
运行程序时报错,raised exception class EInvalidOperation with message 'Canvasdo
es not allow
drawing'.Process stopped.Use Step or Run to continue.
但是单步调试时程序很正常,可以用另一个线程生成Form2对象并显示出来。
请问这是为什么?
 
有两个窗体Form1和Form2,还有一个线程对象MyThread:
在Form1有一个按钮,实现功能如下:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyThread *pMyThread = new MyThread(true);
pMyThread->Resume();
}
在线程对象MyThread实现功能如下:
void __fastcall MyThread::Execute()
{
TForm2 *pForm2 = new TForm2(Application);
pForm2->ShowModal();
}
运行程序时报错,raised exception class EInvalidOperation with message 'Canvasdo
es not allow
drawing'.Process stopped.Use Step or Run to continue.
但是单步调试时程序很正常,可以用另一个线程生成Form2对象并显示出来。
请问这是为什么?
 
还有一个问题想问问:
就是“在主VCL线程生成的窗体”和“在其他线程生成的窗体”有什么不同?
我看过一些多线程的例子都是在主线程生成对象,在其他线程进行运算后,执行Synchronize()进入主线程更新对象。没有看到过在其他线程动态生成对象的。
难道在其他线程就不可以new TForm2么?
 
我对BCB不熟悉,回答你第二个问题吧。
“在主VCL线程生成的窗体”和“在其他线程生成的窗体”没有什么区别,在其他线程就可以new TForm2的。
问题是线程同步问题比较麻烦,除非你不跟主线程进行数据交换或很少交换。因为界面往往输入输出数据比较多,所以很少或尽量不在线程中使用Form。你说的Synchronize()它就是用于线程同步的。
 
这里涉及到VCL的缺陷问题,即线程并行中访问会造成冲突,但如果只在一个线程里就不会
有问题。Synchronize就是来解决这个问题的,它通过调用方法来访问VCL。并不是每个子
线程直接执行Synchronize,而是通过主线程实现的。主线程接受通知是按顺序一个接一个
的,这就避免了对VCL的并行访问,也就避免的冲突。
你的问题就是这样的冲突问题,用Synchronize来调用方法就可以了。
 

我看过一些多线程的例子都是在主线程生成对象,在其他线程进行运算后,执Synchronize()进入主线程更新对象。
如果执行Synchronize()的话,会把生成并显示Form2的工作放到主VCL线程去执行,那样做的话不符合我的本意呀,我是想两个线程各自生成并处理各自的窗体,而不是想主线程处理多个窗体呀。
 
好像有的说“BCB的线程里没有消息循环”,有的说“本来Application多窗口就是一个线程管理的。要自己创建在线程内new自己用sdk 写吧。new 一个vcl的窗口不太可行。”
还望其他朋友给点比较正确的理论给我。
 
后退
顶部