问题是这样的:
一个列表A,我要遍历A中的每个条目,如果遍历的过程中发现某个条目的情况不理想,我就会删除这个条目,同时外部还有可能增加条目。大概如下
for i := 0 to AList.Count - 1 do
begin
  if AList[i] = 某种逻辑 then
    Delete[i];
  //同时外部有 Alist.Add(。) 
end;
大概就这么情况,这样如何保证AList的访问安全性?求助。
这个问题我想大家多多少少都碰到过,希望大家多多拋玉,谢谢了!

解决方案 »

  1.   


    for i :=  AList.Count - 1 to 0 do
    begin
      if AList[i = 某种逻辑 then
      Delete[i];
      //同时外部有 Alist.Add(。) 
    end;]
      

  2.   

    1、downto
    2、使用同步技术
      

  3.   

    现在的问题用Downto循环也解决不了。
    比如现在的List依次存储着A,B,C,D,
    for i := ALst.Count - 1 downto 0 do
    begin
      //这种情况对于在D后面增加元素没有关系,
      //但是程序在收到消息可能在处理D的时候,就删除掉A,B,C
     //现在面临的情况是,List中前面的元素可能被删除,后面的元素可能增加
      //不知道用什么算法比较合适
    end;
      

  4.   

    用synchronize或者临界区把列表保护起来
    另外要用downto否则会报错的
    被临界区或者synchronize保护的列表除非你让出使用权,否则其他修改的程序处于阻塞状态
      

  5.   

    LS方法不可取,如果是多线程处理挂起再唤醒后他自己的循环是需要重新判断list的count和值的
    推荐用数据库存储列表内容,他很好的解决了互斥等问题,不要自己写循环遍历,直接从库中读取列表内容进行修改和添加等操作,如果出于显示需要,你再写入list就可以了
      

  6.   

    看情况而定
    synchronize是用在线程中的函数或者方法上,表示该方法执行时,其中使用的变量不能被其他线程使用
    临界区可以用在公用变量里,也就是多个线程试图访问一个临界区内的变量时,会进入阻塞状态,只有一个线程可以进入临界区,直到那个临界区释放其他线程才能进入
    如果说你只是要循环判断并且删除或修改其中的某条记录的话可以把整个判断代码放到临界区里,当然要注意1判断和修改时间不能过长,2 结束后释放临界区,3 所有试图访问该列表的代码都要用临界区包起来,4 尽量避免多线程死锁
      

  7.   

    说错了,线程类的Synchronize的过程,此过程需要一个无参数的procedure
    给你个例子
    VCL实现同步的另一种方法就是调用线程类的Synchronize的过程,此过程需要一个无参数的procedure,故在此procedure中无法传递参数值,但可以通过类的成员来实现。在类的Execute中只须调用Synchronize就可以了。实现:               关键在于对Synchronize参数的定义。定义一个无参数的procedure通过它来访问类的成员变量szName和nIndex。在类的重载Execute中调用Synchronize。子类的定义如下:
    unit TChildThread;interfaceuses =Classes,Messages,Windows,SysUtils;const MAX_LEN = 260;typeTChildThreads = class(TThread)private      { Private declarations }protectedprocedure Execute; override;//同步函数的声明 
    procedure UpdateData;public      szName : array[0..MAX_LEN] of Char;  nIndex : Integer;end;implementationuses         Unit1;{ Important: Methods and properties of objects in VCL or CLX can only be usedin a method called using Synchronize, for example,        Synchronize(UpdateCaption);and UpdateCaption could look like,      procedure TChildThread.UpdateCaption;     begin        Form1.Caption := 'Updated in a thread';      end; }{ TChildThread }//同步函数的实现procedure TChildThreads.UpdateData;begin         Form1.ShowData.Items.Add(PChar(@szName));end;procedure TChildThreads.Execute;begin{ Place thread code here }//调用同步过程Synchronize(UpdateData);end;end.
    主程的设计与《Delphi中多线程用消息实现VCL数据同步显示》基本一致,但为了与其显示相同结果,在生成子线程中语句顺序作了一下调整。以下代码仅显示与上一篇不同的一个过程,其它代码不再赘述。
    procedure TForm1.StartThreadsClick(Sender: TObject);var         oChildThread : array[0..1000] of TChildThreads;i : Integer;begin        For i := 0 to 1000 dobegin      oChildThread[i] := TChildThreads.Create(true);    //注意这里的代码与消息同步中的顺序。     oChildThread[i].nIndex := i;      strcopy(@oChildThread[i].szName,PChar('Child' + IntToStr(i)));      oChildThread[i].Resume;end;end;===============================================另一个例子:http://topic.csdn.net/t/20011015/02/323001.html   unit    Unit1;   
        
       interface   
        
       uses   
           Windows,    Messages,    SysUtils,    Variants,    Classes,    Graphics,    Controls,    Forms,   
           Dialogs,    StdCtrls,    ExtCtrls;   
        
       type   
           TForm1    =    class(TForm)   
               Button1:    TButton;   
               Edit1:    TEdit;   
               Image1:    TImage;   
               procedure    Button1Click(Sender:    TObject);   
           private   
               {    Private    declarations    }   
           public   
               {    Public    declarations    }   
           end;   
        
           TMyThread    =    class(TThread)   
           private   
               child    :    TComponent;   
        
           public   
               procedure    draw;   
               constructor    Create(parent    :    TComponent);   
               procedure    Execute;    override;   
        
           end;   
        
       var   
           Form1:    TForm1;   
       implementation   
        
       {$R    *.dfm}   
        
       {    TMyThread    }   
        
       constructor    TMyThread.Create(parent:    TComponent);   
       begin   
           child    :=    parent;   
           inherited    Create(false);   
       end;   
        
       procedure    TMyThread.draw;   
       begin   
           if    (child    is    TEdit)    then   
           begin   
               (child    as    TEdit).Text    :=    'OK';   
           end   
           else    if(child    is    TImage)    then   
           begin   
               (child    as    TImage).Canvas.Brush.Color    :=    clBlue;   
               (child    as    TImage).Canvas.FillRect(rect(0,0,100,100));   
           end;   
       end;   
        
       procedure    TMyThread.Execute;   
       begin   
           inherited;   
           synchronize(draw);   
           if    Terminated    then    Exit;   
       end;   
        
       procedure    TForm1.Button1Click(Sender:    TObject);   
        
       begin   
           TMythread.Create(Edit1);   
           TMythread.Create(image1);   
       end;  
      

  8.   

    增加一临时BList,对应Alist作为标识。再操作,
      

  9.   

    你用while循环来处理,不要用for to这样的循环。
      

  10.   


    不考虑外部,也应倒序遍历来删
    如果是多线程的,应该使用一个线程安全的list:Tthreadlist