我有一个多线程应用程序(MIDAS)使用
Windows消息与自身进行通信.
主要形式
主窗体接收RDM发送的Windows消息
LogData(“DataToLog”)
因为使用Windows消息,它们具有以下属性
>收到的消息是不可分割的
>接收到的消息按照发送的顺序排队
题:
你可以建议一个更好的方法,而不使用Windows消息吗?
主编号
const UM_LOGDATA = WM_USER+1002; type TLogData = Record Msg : TMsgNum; Src : Integer; Data : String; end; PLogData = ^TLogData; TfrmMain = class(TForm) // private procedure LogData(var Message: TMessage); message UM_LOGDATA; public // end; procedure TfrmMain.LogData(var Message: TMessage); var LData : PLogData; begin LData := PLogData(Message.LParam); SaveData(LData.Msg,LData.Src,LData.Data); Dispose(LData); end;
RDM代码
procedure TPostBoxRdm.LogData(DataToLog : String); var WMsg : TMessage; LData : PLogData; Msg : TMsgNum; begin Msg := MSG_POSTBox_RDM; WMsg.LParamLo := Integer(Msg); WMsg.LParamHi := Length(DataToLog); new(LData); LData.Msg := Msg; LData.Src := 255; LData.Data := DataToLog; WMsg.LParam := Integer(LData); PostMessage(frmMain.Handle,UM_LOGDATA,Integer(Msg),WMsg.LParam); end;
编辑:
为什么我要摆脱Windows消息:
>我想将应用程序转换为Windows服务
>当系统正忙 – Windows消息缓冲区已满,事情变慢
解决方法
使用命名管道.如果你不知道如何使用它们,那么现在是学习的时候了.
使用命名管道,您可以发送任何类型的数据结构(只要服务器和客户端知道该数据结构是什么).我通常使用一系列记录来发送大量的信息.很方便
我使用Russell Libby的免费(和开源)命名管道组件.配有一个TPipeServer和一个TPipeClient可视化组件.他们使用命名管道非常简单,命名管道非常适合进程间通信(IPC).
You can get the component here.源代码描述如下://说明:为Delphi设置客户机和服务器命名的管道组件,as
//很好的控制台管道重定向组件.
此外,Russell帮助我在Experts-Exchange上使用旧版本的这个组件,在控制台应用程序中通过命名管道发送/接收消息.这可能有助于作为使用他的组件让您开始运行的指南.请注意,在VCL应用程序或服务中,您不需要像我在此控制台应用程序中编写自己的消息循环.
program CmdClient; {$APPTYPE CONSOLE} uses Windows,Messages,SysUtils,Pipes; type TPipeEventHandler = class(TObject) public procedure OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD); end; procedure TPipeEventHandler.OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD); begin WriteLn('On Pipe Sent has executed!'); end; var lpMsg: TMsg; WideChars: Array [0..255] of WideChar; myString: String; iLength: Integer; pcHandler: TPipeClient; peHandler: TPipeEventHandler; begin // Create message queue for application PeekMessage(lpMsg,WM_USER,PM_NOREMOVE); // Create client pipe handler pcHandler:=TPipeClient.CreateUnowned; // Resource protection try // Create event handler peHandler:=TPipeEventHandler.Create; // Resource protection try // Setup clien pipe pcHandler.PipeName:='myNamedPipe'; pcHandler.ServerName:='.'; pcHandler.OnPipeSent:=peHandler.OnPipeSent; // Resource protection try // Connect if pcHandler.Connect(5000) then begin // Dispatch messages for pipe client while PeekMessage(lpMsg,PM_REMOVE) do DispatchMessage(lpMsg); // Setup for send myString:='the message I am sending'; iLength:=Length(myString) + 1; StringToWideChar(myString,wideChars,iLength); // Send pipe message if pcHandler.Write(wideChars,iLength * 2) then begin // Flush the pipe buffers pcHandler.FlushPipeBuffers; // Get the message if GetMessage(lpMsg,pcHandler.WindowHandle,0) then DispatchMessage(lpMsg); end; end else // Failed to connect WriteLn('Failed to connect to ',pcHandler.PipeName); finally // Show complete Write('Complete...'); // Delay ReadLn; end; finally // Disconnect event handler pcHandler.OnPipeSent:=nil; // Free event handler peHandler.Free; end; finally // Free pipe client pcHandler.Free; end; end.