请问如何在dll中使用多线程机制。 想在dll中使用多线程机制,我应该怎么解决?麻烦说得稍详细一些,谢谢各位! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 参考一下:Classes.pasvar WakeMainThread: TNodifyEvent = nil;在D6 Thread中使用Synchronize方法,因为它是调用WakeMainThread方法来实现,而在普通的Application中WakeMainThread是被赋值了的,对应是Application.WakeMainThread, 而当你如果你是写DLL, Form, 虽然它有Application,但是它不同于你的调用的Application,我试了一下,将一个普通Application,调用一个DLL中的Application,它们的Handle和Address是不相同的,也就是说在DLL中如果你调用线程中的Synchronize方法,那么它会失败,甚至于会引起错误或一直阻塞线程,原因就是DLL中Classes.WakeMainThread没有给赋值,然后线程却一直在阻塞进程的运行(wait for), 情况差不多是这样: procedure TMyThread.Execute;begin ... Synchronize(SomeThing); ...end;procedure TThread.Synchronize(Method: TThreadMethod);var SyncProc: TSyncProc;begin SyncProc.Signal := CreateEvent(nil, True, False, nil); ... FMethod := Method; SyncProc.Thread := Self; SyncList.Add(@SyncProc); if Assigned(WakeMainThread) then //DLL中它是没有值的。一直执行到waitfor WakeMainThread(Self);//如是普通Application,那么它会去调用CheckSynchronize,将SyncProc.Signal进行置位,那下面的WaitFor函数会马上返回 LeaveCriticalSection(ThreadLock); try WaitForSingleObject(SyncProc.Signal, INFINITE); //好了,阻塞进程了,你这线程完了,INFINITE是无限长时间,这线程一直等到天亮SyncProc.Signal只有处理了CheckSynchronize才会被置位。哈哈。 finally EnterCriticalSection(ThreadLock); end; ...end;所以如果想在你的DLL中进行VCL组件同步,你必须写自己的WakeMainThread过程,像Application那样。 constructor TDLLForm.Create(AOwner: TComponent);begin Classes.WakeMainThread := WakeMainThread; inherited Create(AOwner);end;TDLLForm.WndProc(var Msg: TMessage);begin case Msg.Msg of ... WM_NULL: CheckSynchronize; end;end;procedure TDLLForm.WakeMainThread(Sender: TObject);begin PostMessage(Handle, WM_NULL, 0, 0); //or直接调用同步。那在WndProc就不用再处理WM_NULL消息了。 //CheckSynchronize;end;因为在普通Application中还有一个原因它会调用CheckSynchronize,就是当PeekMessage不了消息时(没有消息时,空闲时候),也会调用它,这一步就不好做了,你的DLLForm是不会去PeekMessage,只有你的线程才会去PeekMessage,而线程的PeekMessage只是对自己线程消息(GetCurrenThreadID)有效,你可以试试在DLLForm中加一个TTimer,定时给自己发消息,像作Idle事件处理. http://www.clevercomponents.com/articles/article019/delphi6sync.asp 不太喜欢用DELPHI封装的 呵呵 可能对其封装也还不是太熟 不过看了TThread里面的代码 也差不多 就是 线程互斥的时候多注意些 TApplication类中有方法:OnTaskbar吗? 关于计算字段的使用..? 有劳各位看一眼!自动生成SID? 在线等待(如何将ADOQuery中的数据保存到某个数据表中) 怎样根据对方的IP地址获取其机器名? 有谁有DELHPI发短信的源码 如何在DLL中放置资源!!!!!!!高手请入!!! 内详 收藏 不显示删除回复显示所有回复显示星级回复显示得分回复 一个小型的酒店让我帮助开发 Delphi和Oracle数据库中Delete的问题 如何确定窗口的位置 delphi里面做报表用什么好啊
Classes.pasvar
WakeMainThread: TNodifyEvent = nil;在D6 Thread中使用Synchronize方法,因为它是调用WakeMainThread方法来实现,而在普通的Application中WakeMainThread是被赋值了的,对应是Application.WakeMainThread, 而当你如果你是写DLL, Form, 虽然它有Application,但是它不同于你的调用的Application,我试了一下,将一个普通Application,调用一个DLL中的Application,它们的Handle和Address是不相同的,
也就是说在DLL中如果你调用线程中的Synchronize方法,那么它会失败,甚至于会引起错误或一直阻塞线程,原因就是DLL中Classes.WakeMainThread没有给赋值,然后线程却一直在阻塞进程的运行(wait for),
情况差不多是这样:
procedure TMyThread.Execute;
begin
...
Synchronize(SomeThing);
...
end;procedure TThread.Synchronize(Method: TThreadMethod);
var
SyncProc: TSyncProc;
begin
SyncProc.Signal := CreateEvent(nil, True, False, nil);
...
FMethod := Method;
SyncProc.Thread := Self;
SyncList.Add(@SyncProc);
if Assigned(WakeMainThread) then //DLL中它是没有值的。一直执行到waitfor
WakeMainThread(Self);//如是普通Application,那么它会去调用CheckSynchronize,将SyncProc.Signal进行置位,那下面的WaitFor函数会马上返回
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE); //好了,阻塞进程了,你这线程完了,INFINITE是无限长时间,这线程一直等到天亮SyncProc.Signal只有处理了CheckSynchronize才会被置位。哈哈。
finally
EnterCriticalSection(ThreadLock);
end;
...
end;所以如果想在你的DLL中进行VCL组件同步,你必须写自己的WakeMainThread过程,像Application那样。
constructor TDLLForm.Create(AOwner: TComponent);
begin
Classes.WakeMainThread := WakeMainThread;
inherited Create(AOwner);
end;TDLLForm.WndProc(var Msg: TMessage);
begin
case Msg.Msg of
...
WM_NULL: CheckSynchronize;
end;
end;procedure TDLLForm.WakeMainThread(Sender: TObject);
begin
PostMessage(Handle, WM_NULL, 0, 0);
//or直接调用同步。那在WndProc就不用再处理WM_NULL消息了。
//CheckSynchronize;
end;因为在普通Application中还有一个原因它会调用CheckSynchronize,就是当PeekMessage不了消息时(没有消息时,空闲时候),也会调用它,这一步就不好做了,你的DLLForm是不会去PeekMessage,只有你的线程才会去PeekMessage,而线程的PeekMessage只是对自己线程消息(GetCurrenThreadID)有效,你可以试试在DLLForm中加一个TTimer,定时给自己发消息,像作Idle事件处理.