线程中使用Synchronize同步Frame数据出错

keeley20 2010-11-27 04:54:45
线程单元代码如下:
type
TProcessCom =class(TThread)
private
sSocket:TCustomWinSocket;
lstItem:TListItem;
sComm:Byte;
sString:AnsiString;
pStrList, pStrList2:TStringList;
SocketData: TSocketData;
protected
procedure Execute; override;
procedure DOSynJob;
Public
constructor Create(FSocket:TCustomWinsocket;FComm:Byte;FString:AnsiString);
destructor Destroy; override;
end;

implementation
uses UnitMain;

constructor TProcessCom.Create(FSocket:TCustomWinsocket;FComm:Byte;FString:AnsiString);
begin
inherited Create(False);
sSocket:=FSocket;
sComm:=FComm;
sString:=FString;
FreeOnTerminate:=True;
Suspended:=False;
end;

destructor TProcessCom.Destroy;
begin
inherited Destroy;
end;

Function Explode(sDelimiter: string; sSource: String): TStringList;
Var
c: Word;
Begin
Result := TStringList.Create;
C := 0;
While sSource <> '' Do
Begin
If Pos(sDelimiter, sSource) > 0 Then
Begin
Result.Add(Copy(sSource, 1, Pos(sDelimiter, sSource) - 1 ));
Delete(sSource, 1, Length(Result[c]) + Length(sDelimiter));
End
Else
Begin
Result.Add(sSource);
sSource := ''
End;
Inc(c);
End;
End;

procedure TProcessCom.Execute;
var
lstTemp:TListItem;
begin
if sSocket.Data = nil then begin
SocketData := TSocketData.Create;
sSocket.Data := SocketData;
end;
case sComm of
PACK_AUTH:
begin
pStrList := Explode('|',sString);
if pStrList.Count <> 7 then begin
FormMain.DisconnectSocket(sSocket);
exit;
end else begin
Synchronize(dosynJob);
end;
end;
end;
if pStrList<>nil then pStrList.Free;

end;

procedure TProcessCom.DOSynJob;
var
IpAddr:AnsiString;
begin
IpAddr:=GetIPtoAdder(sSocket.RemoteAddress);
lstItem:=FrameOnlineServer.OnlineLV.Items.Add;// 访问VCL就出错
lstItem.Caption:=sSocket.RemoteAddress;
lstItem.SubItems.Add(string(IpAddr));
lstItem.SubItems.Add(pStrList[1]);
lstItem.SubItems.Add(pStrList[8]);
lstItem.SubItems.Add(pStrList[2]);
lstItem.SubItems.Add(pStrList[3]);
lstItem.SubItems.Add(pStrList[4]);
lstItem.SubItems.Add(pStrList[0]);
lstItem.SubItems.Add('test');
lstItem.SubItemImages[2]:=GetFlag(pStrList[8]);
lstItem.SubItems.Objects[0]:=sSocket;
lstItem.ImageIndex:=143;
lstItem.OverlayIndex:=137;
AddLog('添加主机成功: ' + sSocket.RemoteAddress,clBlue);
TSocketData(sSocket.Data).lstConnectionItem := lstitem;
TSocketData(sSocket.Data).sUserPath := pStrList.Strings[1];
TSocketData(sSocket.Data).sRemoteHost := sSocket.RemoteAddress;
CountConnections;
end;

end.

FrameOnlineServer在出窗体创建的时候就Create了,线程调用是在socket的Onread事件里面 TProcessCom.Create(Socket,bByte,tempStr);
调试的时候看到数据传递时没有出错的,本来这一个单元不是线程,就是直接往FrameOnlineServer添加数据,不会出错。
可我想改成线程来处理Socket接收到的数据,不知道哪里出错了,新手学delphi,各位大牛帮忙看看。
...全文
154 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
keeley20 2010-12-03
  • 打赏
  • 举报
回复
谢谢各位的热心帮助,虽然问题没有彻底解决,但我还是学到不少东西,这个线程的功能我直接在在socket的Onread事件里面处理,在这里另生成线程确实画蛇添足。
JPEXE 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 keeley20 的回复:]
错误信息 大致就是Access error,反正是提示访问错误之类,代码我已经改动了,放弃了这种方式,但我还是想知道为什么同步的时候不能访问。
[/Quote]
比较大的可能性应该还是访问到尚未被创建的对象了,主窗体点右键菜单中选择"Creation Order..."看看调整一下创建顺序。
sanguomi 2010-11-30
  • 打赏
  • 举报
回复
代码多不, 要不给我编译次。
keeley20 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 jpexe 的回复:]

报错信息?早该贴出来,省得瞎猜。
[/Quote]
错误信息 大致就是Access error,反正是提示访问错误之类,代码我已经改动了,放弃了这种方式,但我还是想知道为什么同步的时候不能访问。
JPEXE 2010-11-30
  • 打赏
  • 举报
回复
报错信息?早该贴出来,省得瞎猜。
keeley20 2010-11-30
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 sanguomi 的回复:]

你的 Frame的在你调用时候创建对象没?
[/Quote]
我的Frame在主窗体Create的时候就生成了
sanguomi 2010-11-30
  • 打赏
  • 举报
回复
你的 Frame的在你调用时候创建对象没?
keeley20 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sz_haitao 的回复:]

FrameOnlineServer是在主窗体的?怎么前面没有“formmain.”?
[/Quote]
FrameOnlineServer不是主窗体里面的,是我新建的一个Frame,当然后面绑在了FormMain的一个Panel上面
程序代码没错,错就错在同步事件里面的lstItem:=FrameOnlineServer.OnlineLV.Items.Add; 提示访问出错
haitao 2010-11-29
  • 打赏
  • 举报
回复
FrameOnlineServer是在主窗体的?怎么前面没有“formmain.”?
keeley20 2010-11-29
  • 打赏
  • 举报
回复
问题补充

IpAddr:=GetIPtoAdder(sSocket.RemoteAddress);
FormMain.Caption:='test';//这里并没有出错
lstItem:=FrameOnlineServer.OnlineLV.Items.Add; //这里访问就出错了


我尝试访问主窗体,发现并没报错,为什么访问其他Frame就出错了。
keeley20 2010-11-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sz_haitao 的回复:]

使用了Synchronize,访问vcl应该只会慢而不会出错啊

不过,线程最好是不要主动去操作vcl,而是通过一个消息或公共变量来通知主线程,由它主动按通知内容进行vcl的修改
[/Quote]
同样谢谢楼上回复。
我的线程调用是在ServerSocket的Onread事件里面 TProcessCom.Create(Socket,bByte,tempStr),我设想的目的就是减轻ServerSocket的负担(不知道对不对),楼上sz_haitao大牛说“使用了Synchronize,访问vcl应该只会慢”是否有理论上的依据,如果确实如此,那我这么做岂不是画蛇添足了,另外,我还是想知道我的代码哪里出错了。
haitao 2010-11-29
  • 打赏
  • 举报
回复
使用了Synchronize,访问vcl应该只会慢而不会出错啊

不过,线程最好是不要主动去操作vcl,而是通过一个消息或公共变量来通知主线程,由它主动按通知内容进行vcl的修改
keeley20 2010-11-29
  • 打赏
  • 举报
回复
谢谢楼上回复,线程同步到VCL也没有啥不好的,这个程序是做服务器用的,用Onidle估计达不到要求,另我上面的线程代码哪里出了错,或者是FrameOnlineServer里面要怎么设置,还请多指教。
haitao 2010-11-29
  • 打赏
  • 举报
回复
是不是就是因为后绑的,导致Synchronize没把它算入主界面的?
罗捷捷 2010-11-28
  • 打赏
  • 举报
回复
不是很理解你为什么要直接同步到VCL
我用线程一般是用TStringList或着TList,然后MainForm的OnIdle事件读列表数据就行了
keeley20 2010-11-28
  • 打赏
  • 举报
回复
帖子别沉了,明天周末休息,不能上网了,各位大牛走过路过的帮忙看看吧
keeley20 2010-11-27
  • 打赏
  • 举报
回复
谢谢楼上大牛看我的贴,确定,单步跟到这里就出错
sanguomi 2010-11-27
  • 打赏
  • 举报
回复
lstItem:=FrameOnlineServer.OnlineLV.Items.Add;// 访问VCL就出错

确定错误是由这行引起的?

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧