现在写的程序,底层采用VC++写的采集接口,利用回调函数机制和消息机制将采集到数据转发给delphi做进一步的处理,目前处理小批量数据没有问题,但是数据量增大时,程序界面卡死。由于将VC++接口做成VCL控件形式,某前只能在主线程接收数据。我想实现界面不卡死大虾们有啥建议?

解决方案 »

  1.   

    是不是处理太复杂?或者消息太多,一次把很多数据打包发送cpu处理会简单一些。
      

  2.   

    给子线程发消息是很容易的 用PostThreadMessage就行:PostThreadMessage(ThreadID, YOUR_MESSAGE, 0, 0);用法和PostMessage相似。
    在子线程中使用 while GetMessage(....)do 获得消息另外 能把回调函数的定义贴出来吗
      

  3.   


    在底层VC++中有这么个函数类型:typedef void (CALLBACK* NOTIFYPROC)(LPVOID, ClientContext*, UINT nCode);当有数据信息接收完毕后,使用m_pNotifyProc((LPVOID) m_pFrame, pContext, NC_RECEIVE);来通知delphi层去取数据。
    在delphi层有一下代码:procedure TIOCPSEVER1.callback(S:tsocket;Even:integer);stdcall;
    begin
      PostMessage(FwindowHandle,wm_user+Even,s,0);
    end;
    在控件初始化时:procedure TIOCPSEVER1.SetActive(const Value: boolean);
    begin
      if value then
      begin
        if not FActive then
        begin
         if init(@TIOCPSEVER1.callback,Fport) then FActive := Value;
        end;
      end
      else
      begin
        if FActive then
        begin
          shutdown;
          FActive := value;  
        end;
      end;end;
    VC++底层初始化时将m_pNotifyProc=TIOCPSEVER1.callbac。消息处理函数:
    procedure TIOCPSEVER1.WndProc(var Msg: TMessage);
    begin
      with msg do
        case Msg of
        (WM_USER+0):
        begin    end;
        (WM_USER+1):
        begin
          if Assigned(OnConnect) then
            OnConnect(WParam);
        end;
        (WM_USER+2):
        begin
          if Assigned(OnDisConnect) then
             OnDisConnect(WParam);
        end;
        (WM_USER+3):
        begin
          if Assigned(OnTransmit) then
             OnTransmit(WParam);
        end;
        (WM_USER+4):
        begin
          DoExecute(WParam);
        end;
        (WM_USER+5):
        begin
          if Assigned(ONTRANSMITSucess) then
            ONTRANSMITSucess(WParam);
        end;
        else
          Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
        end;
    end;
    我想要是能改下TIOCPSEVER1.callback(S:tsocket;Even:integer);这个改成向线程中发送消息,在线程完成事件处理应该可以改善下。
      

  4.   

    另外,我想问下PostThreadMessage(ThreadID, YOUR_MESSAGE, 0, 0);中的线程ID如何获取啊,线程我是使用TThreadl类。
      

  5.   

    我觉得改动不多就能在另一线程中处理
    假定子线程为aThread
    1 改 procedure TIOCPSEVER1.callback(S:tsocket;Even:integer);stdcall;
    begin
      PostMessage(FwindowHandle,wm_user+Even,s,0);
    end;
    为procedure TIOCPSEVER1.callback(S:tsocket;Even:integer);stdcall;
    begin
      PostThreadMessage(aThread.ThreadID,wm_user+Even,s,0);
    end;2 在aThread的类的Execute中做类似如下的处理
    TaThread.Execute;
    var
        msg: TMsg;
    begin
         while GetMessage(msg, 0, 0, 0) do
         begin
             with msg do
             case Msg.message of
            (WM_USER+0):
             begin 
             end;
             (WM_USER+1):
             begin         
                OnConnect(WParam);
             end;
            (WM_USER+2):
            begin
                OnDisConnect(WParam);
             end;
            (WM_USER+3):
            begin       
              OnTransmit(WParam);
           end;
           (WM_USER+4):
           begin
             DoExecute(WParam);
           end;
           (WM_USER+5):
           begin
              ONTRANSMITSucess(WParam);
           end;
         end;
    end;
      

  6.   


    这个功能基本完成了,但是效果还是不好,我的控件还在主线程中,还是需要主线程来转发消息。控件中引用了VC++写的DLL控件,我想问下能在线程中直接使用DLL控件?
      

  7.   

    请问下 DLL是接收完数据再通知delphi呢 还是只是通知delphi去接收数据?
    在你的程序中 你感觉接收数据费时间还是处理数据费时间?
      

  8.   

    没看到DLL的数据接收函数 应该是DLL负责接收数据吧
      

  9.   

    如果不能把数据接收程序放在子线程中 可以考虑把界面程序放在子线程中。不过这样和delphi习惯不一样