zoukankan      html  css  js  c++  java
  • Delphi写的DLL,OCX中多线程一个同步问题

    Delphi写的DLL,OCX中如果使用了TThread.Synchronze(Proc),可能导致线程死锁,原因是无法唤醒EXE中主线程,

    Synchronze并不会进入EXE主线程消息队列.

    下面的程序自动解决此问题,只需要加入DLL,OCX工程文件中,在DLL,OCX中便可以使用TThread.Synchronze(Proc)了,无需再写一行代码。

    //解决Delphi编译的DLL,OCX文件中的线程调用 TThread.Synchronize后挂起无法再激活问题
    //调用了TThread.Synchronize函数的所有工程请包含此文件
    //仅需将此单元包含到工程文件即可
    
    unit Lib.Common.DLLThread;
    
    interface
    
    
    implementation
    
    uses Classes, Windows, Messages;
    
    type
    
      { TDLLSystemController }
    
      TDLLSystemController = class
      private
        FHandle: HWND;
        FPrevWakeMainThread: TNotifyEvent;
        procedure WakeMainThread(Sender: TObject);
        procedure HookSynchronizeWakeup;
        procedure UnhookSynchronizeWakeup;
      protected
        procedure WndProc(var Message: TMessage);
      public
        constructor Create;
        destructor Destroy; override;
      end;
    
    var
      FDLLController:TDLLSystemController;
    
    { TDLLSystemController }
    
    constructor TDLLSystemController.Create;
    begin
      inherited;
      if IsLibrary then
      begin
        FHandle := AllocateHWnd(WndProc);
        HookSynchronizeWakeup;
      end;
    end;
    
    destructor TDLLSystemController.Destroy;
    begin
      if IsLibrary then
      begin
        DeallocateHWnd(FHandle);
        UnhookSynchronizeWakeup;
      end;
      inherited;
    end;
    
    procedure TDLLSystemController.WndProc(var Message: TMessage);
    begin
      case Message.Msg of
        WM_NULL: CheckSynchronize;
      else
        Message.Result := DefWindowProc(FHandle, Message.Msg, Message.wParam, Message.lParam);
      end;
    end;
    
    procedure TDLLSystemController.WakeMainThread(Sender: TObject);
    begin
      PostMessage(FHandle, WM_NULL, 0, 0);
    end;
    
    procedure TDLLSystemController.HookSynchronizeWakeup;
    begin
      FPrevWakeMainThread := Classes.WakeMainThread;
      Classes.WakeMainThread := WakeMainThread;
    end;
    
    procedure TDLLSystemController.UnhookSynchronizeWakeup;
    begin
      Classes.WakeMainThread := FPrevWakeMainThread;
    end;
    
    
    initialization
      if IsLibrary then FDLLController := TDLLSystemController.Create
        else FDLLController:=nil;
    finalization
      if Assigned(FDLLController) then FDLLController.Free;
    end.
  • 相关阅读:
    win安装Theano
    Photoshop
    Sublime Text与LaTeX的结合
    Python开源库的bug
    Pillow库的学习和使用
    对OpenSSL心脏出血漏洞的试验
    Scrapy的学习和使用
    FreeImage库的学习和使用
    gdal库的学习和使用
    VirtualBox安装Debian
  • 原文地址:https://www.cnblogs.com/hezihang/p/3965179.html
Copyright © 2011-2022 走看看