我的想法是启动10个线程,每个线程负责一些ID的操作
比方
第一个线程负责1 2 3 4 5 ... 10,  101 102 103 104 105.. 110 , 201....210,  301...310 ....
第二个负责11 12 13 14 15....20,  111 112 113 114 115...120 , 211....220...........
第三个负责21 22 23 24 25....30,  121 122 123 124 125...130 , 221....230...........
.......现在的问题是listbox中不能正确显示所有经过处理的值,也就是说不能列出1....2000里面所有的整数值因为处理过程中使用了xml,自己注释了它就能正确列出所有的值,不注释就始终显示大多数的(不完整)所以请教大家,线程中该如何使用XMLtype
  TMyThread = class(TThread)
  private
    { Private declarations }
    FStartID,FEndID,FTargeID: Integer;
             
    FStringList:TStrings;                               procedure NewUpdateUI;
    procedure UpdateUI;                       
    procedure work;                              protected
    procedure Execute; override;
  public
    constructor  Create(CreateSuspended: Boolean);
    destructor   Destroy; override;
    property StartID:Integer read FStartID write FStartID;
    ........
//更新UI界面
procedure TMyThread.UpdateUI;
begin
  Form2.ListBox1.Items.AddStrings(FStringList);
end;procedure TMyThread.work;
var
  i,j,k: integer;
  ID: Integer;  XMLDoc: IXMLDocument;
  XMLNode: IXMLNode;begin
  i := FStartID;
  j := 0;
  k := 0;  try
    XMLDoc := NewXMLDocument(WideString('1.0'));      //注释了它和下面一行就每次成功显示所有的ID到LISTBOX
    XMLDoc.Encoding := 'GBK';                         
  except
    FSList.Add('id ' + IntToStr(FStartID) + ' 创建XML失败' );
    Synchronize(NewUpdateUI);
  end;
  While i < 2000 Do
  begin    FStringList.Add( inttostr(i) + ' Accid = ' + IntToStr(AccID) + ' processing...读取计数j=' + inttostr(j) + ' 写入计数k=' + inttostr(k) );
    Inc(j);                 
    if j < 10 then
      inc(i)                
    else
      begin
        j := 0;             
        k := 0;             
        i := i + 90;       
      end;    Sleep(10);
  end;  log.Free;
  FreeAndNil(XMLDoc);
end;procedure TMyThread.Execute;
begin
  { Place thread code here }
  FreeOnTerminate:=True;
  OnTerminate := Form2.ThreadsDone;  Coinitialize(nil); 
  Try 
    work; 
  finally 
    CoUninitialize 
  end;   //最后更新界面,在listbox里面列表经过计算的值
  Synchronize(UpdateUI);end;  //FORM中创建线程代码
  Thread0 := TMyThread.Create(True);
  Thread0.StartID := 1;
  Thread1 := TMyThread.Create(True);
  Thread1.StartID := 11;
  ......
  Thread9 := TMyThread.Create(True);
  Thread9.StartID := 91;
  Thread0.Resume;
  Thread1.Resume;
  .....
  Thread9.Resume;//启动10个线程

解决方案 »

  1.   

    兄弟,偶希望多线程啊,这样子Synchronize(work);岂不是主线程在执行和调用了,和单线程有区别吗?
      

  2.   

    而且吧,无论是否Synchronize(work);来执行,只要work里面有这个XMLDoc ,结果就不正确,少部分数据,本来应该是能输出2000条,始终只输出了1400左右条记录……汗死,不可能多线程里面不让操作xml吧
      

  3.   


      try
        XMLDoc := NewXMLDocument(WideString('1.0'));      //看不懂,为什么一个线程创建一个XMLDoc?你想实现什么功能?
        XMLDoc.Encoding := 'GBK';                         
      except
        FSList.Add('id ' + IntToStr(FStartID) + ' 创建XML失败' );
        Synchronize(NewUpdateUI);
      end;
      

  4.   

    是的,我知道这个需要加锁,不过我操作xml只是在内存中操作,并不保存xml数据到文件也不到控件
    目前的代码中只是创建了xmldoc而已,其余的代码只是按规律产生id,并输出
      

  5.   

    笑青天兄弟来了……
    我本来是打算操作获取到的xmldoc的,后来发现这个多线程代码有问题
    于是注释了所有有可能有问题的代码,基本上就留下了贴出来的代码
    代码中就是产生id,输出id至于为什么留下了xmldoc,是因为我发现注释了它就能正确出结果,不注释就不出正确的结果
      

  6.   

    我上手的程序是个调用webservice的程序,webservice返回的是xml文档,我的代码只是简单修改下xml然后返回给serveice
    因为执行效率的问题,所以我打算采用多线程目前其他部分的代码都被注释了,留下了输出id和创建xml部分,目的是为了发现问题所在
    现在发现输出被执行过的id的时候,不完整,listbox能显示出大多数的id,但不是全部
    如果注释了创建xml部分的代码(就那2行),listbox能显示所有经过处理的id我是把listbox的值都保存到txt文档来查看的
      

  7.   

    XMLDOC我现在代码里面只是定义了下而已……
    我只所以有这个代码,是因为我打算处理一个webservice的返回的XML数据,鉴于速度的需要,采用了多线程
    (就算处理到了xml部分代码,那也是纯内存处理的,不会保存到硬盘上再来读取的)
    不知道是不是真得因为xml不能在多线程里面使用了……高手能给偶答疑解惑吗?
    汗,帖子挂了一天了
      

  8.   

    老大……不是吧,我的work就那几行代码了……
    方便加下qq或者msn吗?我实在受不了了,看了一整天,2眼都茫然了……
    偶是delphi2007写的代码偶发论坛短信给你了
      

  9.   


    unit Unit2;interfaceuses
      Classes,SysUtils,StdCtrls,ActiveX,XMLIntf,XMLDoc,Dialogs;type
      TMyThread = class(TThread)
      private
        { Private declarations }
        FStartID,FEndID:Integer;
        FStringList: TStrings;
        FListBox:TListBox;
        procedure WorkIt;
        procedure HookUI;  protected
        procedure Execute; override;  public
        property    StartID: Integer read FStartID write FStartID;
        property    EndID:   Integer read FEndID write FEndID;
        constructor Create(CreateSuspended: Boolean;ListBox:TListBox);
        destructor  Destroy; override;
      end;implementation
    constructor TMyThread.Create(CreateSuspended: Boolean;ListBox:TListBox);
    begin
      inherited Create(createSuspended);
      FStringList:=TStringList.Create;
      FListBox:=ListBox;
      FreeOnTerminate:=True;
    end;destructor TMyThread.Destroy;
    begin
      FreeAndNil(FStringList);
      inherited;
    end;procedure TMyThread.Execute;
    begin
      { Place thread code here }
      Coinitialize(nil);
      WorkIt;
      Synchronize(HookUI);
      CoUninitialize ;
    end;procedure TMyThread.HookUI;
    begin
      FListBox.Items.AddStrings(FStringList);
    end;procedure TMyThread.WorkIt;
    var
      I,J,K: integer;
      ID: Integer;
      XMLDoc:  IXMLDocument;
      XMLNode: IXMLNode;
    begin
      I := FStartID;
      J := 0;
      K := 0;  try
        XMLDoc := NewXMLDocument(WideString('1.0'));
        XMLDoc.Encoding := 'GBK';
        While I <=2000 Do
        begin
          FStringList.Add( IntToStr(I) + ' Accid = ' + IntToStr(ID) + ' processing...读取计数j=' + IntToStr(j) + ' 写入计数k=' + inttostr(k) );
          Inc(J);
          if J < 10 then   INC(I)
          else
          begin
            J := 0;
            K := 0;
            I := I + 91;
          end;
      end;
      finally
      end;
    end;end.
      

  10.   

    线程代码就那些了,根本灭有其他的,为什么会是2个样子……无语中,兄弟就是用的偶的代码在delphi7中执行?偶用的xp sp2,delphi2007
    msxml是3.0
    偶就犯困啊,这个是为什么呢
      

  11.   


    主线程
    包含ListBox,Buttonvar
      Thread0,Thread1,Thread2..Thread9:TMyThread;
    begin  Thread0:=TMyThread.Create(True,ListBox1);
      Thread0.StartID:=1;
      Thread0.Resume;
      ..
      ..
      

  12.   

    procedure TForm2.ThreadsDone(Sender: TObject);
    begin
      inc(DoneFlags);
      if DoneFlags = 10 then
      begin
        ListBox1.Items.SaveToFile( ExtractFilePath(Application.ExeName) + FormatDateTime('yyyymmddhhmmss',Now()) + '.txt' ) ;
      end;
    end;procedure TMyThread.Execute;
    begin
      { Place thread code here }
      FreeOnTerminate:=True;
      OnTerminate := Form2.ThreadsDone;  Coinitialize(nil);
      Try 
        Synchronize(work);
      finally 
        CoUninitialize 
      end;   //最后更新界面
      Synchronize(UpdateUI);end;这样子给listbox赋值不行?
      

  13.   

    OK,马上测试,你是传入了listbox,偶是用的OnTerminate := Form2.ThreadsDone;
    几分钟
      

  14.   

    FListBox:=ListBox;  //ListBox-----undeclare..... 
      

  15.   

    sorry....声明部分忘记修改了,吼吼
      

  16.   

    XMLDoc不用释放,它是一个接口类型,它内部有个计数器,当对XMLDoc的引用次数等于0时,系统自动释放。