大大救命!!多线程通信中listview的数据老是被修改,如何解决呢?
各位大大,本人写的程序是这样的,由于源码太多太多,只能贴有问题的部分,请各位大大,帮忙解决:
操作过程:
选择lisview1的一个选项,listview1的显示方式为vsReport,点击按钮,向远程客户端发送连接命令,由于每一个项代表一个远程的客户端,所以点击该按钮
就代表操作该主机,此处为控制端代码:
procedure TForm1.Button5Click(Sender: TObject);
begin
if form1.listview1.Selected <> nil then
begin
if listview1.Selected.SubItems.Objects[2] <> nil then
begin
showmessage( '进程监控已经在运行了! ');
exit;
end;
spyitem:=form1.listview1.Selected;
form1.Enabled:=false;
sendcmd( '014 ', edit5.text, True); // 用一个在线套接字,发送消息
beginspy:=false;
end;
end;
然后
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecCMD: string;
pitem:tlistitem;
rs, ss: TMemoryStream;
pCmd: array[0..SizeOf(TSpyCmd) - 1] of Byte;
pBuf: array[0..8191] of Byte;
Read, Size: Integer;
//spyobjects:Tobjects;
begin
RecCMD := AThread.Connection.readln(EOL);
//RecCMD := DecodeBase64(RecCMD);
//showmessage(reccmd);
if Length(RecCMD)> 5 then Exit;
... ...
if AThread.Connection.Tag = 4 then //进程管理
begin
UserProc(AThread, RecCMD);
Exit;
end;
end;
这是 userproc函数的相关代码:
procedure UserProc(AThread: TIdPeerThread; RecCMD: string);
function getfilesize(str: string): string;
{=======================进程管理=========================}
if reccmd = '004 ' then //进程管理
begin
athread.Connection.Tag:=4; //此处为远程主机新建的一个套接字,标示为4
//process_form.show;
athread.data:=spyitem;
tonlineinf(spyitem.data^).process_atrhread:=athread;
athread.Synchronize(form1.show_process);
//sleep(100);
//while athread.Connection.Connected do
//begin
end;
if reccmd = '012 ' then //进程管理
begin
if form1.readseverstream(athread,tempstr) then
begin
Temp_process:=tstringlist.Create;
temp_process.Text:=tempstr;
pitem:=tlistitem(athread.data);
for i:=0 to temp_process.Count-1 do
begin
with tprocess_form(pitem.SubItems.Objects[2]).ListView1.Items.Add do
begin
Caption:= form1.centerstr(temp_process[i], ' <pr_name> ', ' </pr_name> ');
SubItems.Add(form1.centerstr(temp_process[i], ' <pr_id> ', ' </pr_id> '));
SubItems.Add(form1.centerstr(temp_process[i], ' <pr_path> ', ' </pr_path> '));
end;
end;
//showmessage(tempstr);
end;
//end;
end;
end;
这是显示窗体的过程
procedure tform1.show_process;
var
process_form:Tprocess_form;
begin
process_form:=Tprocess_form.Create(self);
//tonlineinf(spyitem.data^).process_atrhread.Data:=spyitem;
spyitem.SubItems.Objects[2]:=process_form;
process_form.pitem:=spyitem;
tonlineinf(spyitem.data^).process_atrhread.Connection.Write( '004 '+EOL);
form1.Enabled:=true;
process_form.Show;
end;
在下搞不懂的是,点listview1第一个项,能正常工作,可是
点多了listview1项,偶尔会发现listview1某项的数据会被修改
请问如何解决:
listview1的数据结构
主机IP 标识ID 计算机名称 操作系统
127.0.01 2037 winpc winxp sp2
...
...
...
执行上面操作的时候,会变成这样
主机IP 标识ID 计算机名称 操作系统
127.0.01 (乱码或者没有数据) winpc winxp sp2
...
...
...
里面任决一列的数据都会被改写,改写的数据是随机的。。。
[解决办法]
线程绝对不能碰UI!!!!---这是天条不可触犯!
两种方法解决:
1.线程里Sendmessae,界面窗口来处理消息,刷新屏幕
2.线程里必须用Synchronize 的方法来刷新屏幕!
[解决办法]
Synchronize