主线程中关于TMemo调用显示问题,我急需大侠们帮助解决 ( 积分: 100 )

  • 主题发起人 主题发起人 huajj
  • 开始时间 开始时间
H

huajj

Unregistered / Unconfirmed
GUEST, unregistred user!
在sock线中或是在自己定义的线程中memo1显示内容非常非常慢,急需大家帮助解决。
调用线程:
procedure TMain_Form.ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TsecuServerThread.Create(true, ClientSocket,self.memo1);
SocketThread.FreeOnTerminate := True;
SocketThread.Resume;
end;

定义线程:
//侦听发起并接收应答处理线程
TsecuServerThread = class(TServerClientThread)
public
Constructor Create(T_Type:boolean;ClientSocket: TServerClientWinSocket;Memostat1:TMemo);
private
protected
Memoq:TMemo;
procedure ClientExecute;
override;
end;
主线程详细内容(有些内容有删除):
Constructor TsecuServerThread.Create(T_Type:boolean;ClientSocket: TServerClientWinSocket;Memostat1:TMemo);
begin
inherited Create(T_Type,ClientSocket);
Memoq := Memostat1;
end;
procedure TsecuServerThread.ClientExecute;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
i: integer;
Ret: integer;
.......
TxReqPkg,TxAnsPkg: array [0..600] of char;
TxLen,Recv_Len: integer;
str:string;
begin
while not Terminated and ClientSocket.Connecteddo
begin
FD_ZERO(FDSet);
FD_SET(ClientSocket.SocketHandle, FDSet);
TimeVal.tv_sec := 0;
TimeVal.tv_usec := 500;
if (select(0, @FDSet, nil, nil, @TimeVal) >
0) and not Terminated then
if ClientSocket.ReceiveBuf(FDSet, -1) = 0 then
break
else
begin
//端口校验
if ClientSocket.LocalPort = cfg.scserver_port then
begin
// 创建 sockstream
ScktStream := TWinSocketStream.Create(ClientSocket, 1000);
fillmemory(@TxReqPkg,sizeof(TxReqPkg),32);
// 接收银行请求
Recv_Len := Recv_HsPkg(ClientSocket,scktStream,TxReqPkg);
// 接收错误,结束
if (Recv_Len <
0) then
begin
try
ScktStream.Free;
ClientSocket.Close;
except
end;
exit;
end;
copymemory(@BankReq_Trans,@TxReqPkg,sizeof(BankReq_Trans))
GetKeys;
Recv_Len:=recvpackage(BankReq_Trans);
if cfg.comm_pack=1 then
begin
Self.Memoq.Clear;
Self.Memoq.Lines.Add('************银行请求***********');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('交易时间(时分):');
Self.Memoq.Lines.Add('交易日期(月日):');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
end
Ret := Send_HsPkg(ClientSocket,scktStream,TxAnsPkg,Recv_Len);
// 发送失败
if (Ret = -1) or (Ret = -2) then
begin
try
scktstream.Free;
ClientSocket.Close;
except
end;
exit;
end;
// 关闭 socket
try
scktstream.Free;
ClientSocket.Close;
except
end;
end;
end;
end;
end;
 
在sock线中或是在自己定义的线程中memo1显示内容非常非常慢,急需大家帮助解决。
调用线程:
procedure TMain_Form.ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TsecuServerThread.Create(true, ClientSocket,self.memo1);
SocketThread.FreeOnTerminate := True;
SocketThread.Resume;
end;

定义线程:
//侦听发起并接收应答处理线程
TsecuServerThread = class(TServerClientThread)
public
Constructor Create(T_Type:boolean;ClientSocket: TServerClientWinSocket;Memostat1:TMemo);
private
protected
Memoq:TMemo;
procedure ClientExecute;
override;
end;
主线程详细内容(有些内容有删除):
Constructor TsecuServerThread.Create(T_Type:boolean;ClientSocket: TServerClientWinSocket;Memostat1:TMemo);
begin
inherited Create(T_Type,ClientSocket);
Memoq := Memostat1;
end;
procedure TsecuServerThread.ClientExecute;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
i: integer;
Ret: integer;
.......
TxReqPkg,TxAnsPkg: array [0..600] of char;
TxLen,Recv_Len: integer;
str:string;
begin
while not Terminated and ClientSocket.Connecteddo
begin
FD_ZERO(FDSet);
FD_SET(ClientSocket.SocketHandle, FDSet);
TimeVal.tv_sec := 0;
TimeVal.tv_usec := 500;
if (select(0, @FDSet, nil, nil, @TimeVal) >
0) and not Terminated then
if ClientSocket.ReceiveBuf(FDSet, -1) = 0 then
break
else
begin
//端口校验
if ClientSocket.LocalPort = cfg.scserver_port then
begin
// 创建 sockstream
ScktStream := TWinSocketStream.Create(ClientSocket, 1000);
fillmemory(@TxReqPkg,sizeof(TxReqPkg),32);
// 接收银行请求
Recv_Len := Recv_HsPkg(ClientSocket,scktStream,TxReqPkg);
// 接收错误,结束
if (Recv_Len <
0) then
begin
try
ScktStream.Free;
ClientSocket.Close;
except
end;
exit;
end;
copymemory(@BankReq_Trans,@TxReqPkg,sizeof(BankReq_Trans))
GetKeys;
Recv_Len:=recvpackage(BankReq_Trans);
if cfg.comm_pack=1 then
begin
Self.Memoq.Clear;
Self.Memoq.Lines.Add('************银行请求***********');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('交易时间(时分):');
Self.Memoq.Lines.Add('交易日期(月日):');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
Self.Memoq.Lines.Add('委托方式:');
end
Ret := Send_HsPkg(ClientSocket,scktStream,TxAnsPkg,Recv_Len);
// 发送失败
if (Ret = -1) or (Ret = -2) then
begin
try
scktstream.Free;
ClientSocket.Close;
except
end;
exit;
end;
// 关闭 socket
try
scktstream.Free;
ClientSocket.Close;
except
end;
end;
end;
end;
end;
 
在线程中操作可视化控件行吗?
 
我觉得楼主这样操作VCL控件可能会出现同步的问题,一般操作VCL时应用Synchronize(方法名)来调用。
 
应该用Synchronize同步吧
 
在多线程中调用vcl的时候,必须使用Synchronize来保持同步,你的问题就在这里了!
 
Tmemo中显示的东西比较多的话,速度就是比较慢
 
应该向Applicaiton.Handle发送消息来让主线程操作TMemo,具体方法可以有两个(其他的可以自己想):
1、定义几种消息,或一种消息定义几种参数(通过消息的wParam和lParam传递),主窗体根据消息类型或参数值来向TMemo添加内容。
2、定义一种消息,在需要附加信息的时候,辅助线程创建消息的文字内容(PChar类型),把指针的值作为参数随消息发送到主线程,主线程处理完毕后负责释放。
还有,印象中用Append比Add好像要好一点,如果消息积累的太多,好像Append会把旧的内容清空。
辅助线程是不能操作VCL中的可见控件的,有可能(以一个不太大的几率)导致程序失去响应。
 
多个线程同时操作一个对象memo时肯定回出错的,并且你的memo里的内容肯定是没有规则,很乱的!
 
后退
顶部