首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

大大救命!多线程通信中listview的数据老是被修改,怎么解决呢

2012-02-23 
大大救命!!多线程通信中listview的数据老是被修改,如何解决呢?各位大大,本人写的程序是这样的,由于源码太

大大救命!!多线程通信中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

热点排行