想在dll中使用多线程机制,我应该怎么解决?麻烦说得稍详细一些,谢谢各位!

解决方案 »

  1.   

    参考一下:
    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事件处理.
      

  2.   

    http://www.clevercomponents.com/articles/article019/delphi6sync.asp
      

  3.   

    不太喜欢用DELPHI封装的 呵呵 可能对其封装也还不是太熟 不过看了TThread里面的代码 也差不多 就是 线程互斥的时候多注意些