Y
yanghai0437
Unregistered / Unconfirmed
GUEST, unregistred user!
Synchronize的使用问题,在不同的计算机上使用效果不一样(Synchronize代码的详细分析,PostMessage不能通知到主线程,消息丢失) ( 积分: 200 )<br />Synchronize的使用问题,在不同的计算机上使用效果不一样.
在联想品牌计算机上运行正常,在一台兼容机上运行造成死锁,界面没有反映,
不知道原因。还有一个现象就是我在能够正常执行的计算机上编译后,将可执行程序复制到
兼容机上后也能够正常执行,只要在这台兼容机上编译后就不能正常执行。紧急求助。
我刚才已经仔细分析了Synchronize的运行方式。
第1步:线程调用Synchronize
第2步:Synchronize方法将方法添加到主线程的方法队列中
第3步:马上调用WakeMainThread方法,用PostMessage通知主线程检查同步方法
第4步:主线程收到消息后调用CheckSynchronize方法,执行需要执行的方法,然后产生
SetEvent(SyncProc.signal);
最后:线程收到SyncProc.signal事件信号后Synchronize方法完成。
我发现在这个过程中PostMessage不能通知到主线程,消息丢失,这样造成无法产生SyncProc.signal信号。
以下代码均为delphi6中的classes和Forms中的代码,省略部分代码
procedure TThread.Synchronize(Method: TThreadMethod);
....
if Assigned(WakeMainThread) then
WakeMainThread(Self);
{$IFDEF MSWINDOWS}
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);//这里造成死锁
finally
EnterCriticalSection(ThreadLock);
end;
{$ENDIF}
.....
function CheckSynchronize: Boolean;
begin
...........
{$IFDEF MSWINDOWS}
SetEvent(SyncProc.signal);//在这里产生SyncProc.Signal
{$ENDIF}
..............
end;
procedure TApplication.WakeMainThread(Sender: TObject);
begin
PostMessage(Handle, WM_NULL, 0, 0);//Handle是正确的,但是不能收到这个消息。程序可以跟踪到这里,也就是说PostMessage消息丢失了
end;
procedure TApplication.WndProc(var Message: TMessage);//这个消息处理过程不能收到WakeMainThread发送的WM_NULL消息
begin
............
WM_NULL://这个消息调用下面的过程,再产生SyncProc.Signal,这样在TThread.Synchronize就不会死锁
CheckSynchronize;
//现在的问题是这个消息处理过程不能收到WakeMainThread发送的WM_NULL消息
............
end;
在联想品牌计算机上运行正常,在一台兼容机上运行造成死锁,界面没有反映,
不知道原因。还有一个现象就是我在能够正常执行的计算机上编译后,将可执行程序复制到
兼容机上后也能够正常执行,只要在这台兼容机上编译后就不能正常执行。紧急求助。
我刚才已经仔细分析了Synchronize的运行方式。
第1步:线程调用Synchronize
第2步:Synchronize方法将方法添加到主线程的方法队列中
第3步:马上调用WakeMainThread方法,用PostMessage通知主线程检查同步方法
第4步:主线程收到消息后调用CheckSynchronize方法,执行需要执行的方法,然后产生
SetEvent(SyncProc.signal);
最后:线程收到SyncProc.signal事件信号后Synchronize方法完成。
我发现在这个过程中PostMessage不能通知到主线程,消息丢失,这样造成无法产生SyncProc.signal信号。
以下代码均为delphi6中的classes和Forms中的代码,省略部分代码
procedure TThread.Synchronize(Method: TThreadMethod);
....
if Assigned(WakeMainThread) then
WakeMainThread(Self);
{$IFDEF MSWINDOWS}
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);//这里造成死锁
finally
EnterCriticalSection(ThreadLock);
end;
{$ENDIF}
.....
function CheckSynchronize: Boolean;
begin
...........
{$IFDEF MSWINDOWS}
SetEvent(SyncProc.signal);//在这里产生SyncProc.Signal
{$ENDIF}
..............
end;
procedure TApplication.WakeMainThread(Sender: TObject);
begin
PostMessage(Handle, WM_NULL, 0, 0);//Handle是正确的,但是不能收到这个消息。程序可以跟踪到这里,也就是说PostMessage消息丢失了
end;
procedure TApplication.WndProc(var Message: TMessage);//这个消息处理过程不能收到WakeMainThread发送的WM_NULL消息
begin
............
WM_NULL://这个消息调用下面的过程,再产生SyncProc.Signal,这样在TThread.Synchronize就不会死锁
CheckSynchronize;
//现在的问题是这个消息处理过程不能收到WakeMainThread发送的WM_NULL消息
............
end;