Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Fernando-M

[Resolvido] Thread e TStringList e Add - dar erro

Recommended Posts

Gostaria de execultar o comando

begin
  Lista.Add('Exemplo');
end;
Sendo Lista: TSringList; uma variavel global declarada no Form Principal.

Onde vários Thread precisa adicionar milhares de vezes o comando Lista.Add('Exemplo');

Só que quando coincide de uma Thread execultar o Lista.Add('Exemplo'); ao mesmo tempo que outra dar erro.

Alguém sabe como posso resolver isso.

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema é que uma thread manda um valor antes mesmo que o objeto TStringList tenha terminado de adicionar o valor anterior.

 

faça um teste: Tente contornar a situação utilizando um "flag".

 

Declare uma váriavel do tipo booleana e quando estiver inserindo um valor no TStringList marque como true, após terminar a inserção marque como false.

 

antes de fazer uma inserção (la nas thread) verifique se esta variavel está marcada como true..

 

 

if (Inserindo = false) then
begin
	Inserindo := true;
	Lista.Add('valor');
	Inserindo := false;
end;

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema é que uma thread manda um valor antes mesmo que o objeto TStringList tenha terminado de adicionar o valor anterior.

 

faça um teste: Tente contornar a situação utilizando um "flag".

 

Declare uma váriavel do tipo booleana e quando estiver inserindo um valor no TStringList marque como true, após terminar a inserção marque como false.

 

antes de fazer uma inserção (la nas thread) verifique se esta variavel está marcada como true..

 

 

if (Inserindo = false) then
begin
	Inserindo := true;
	Lista.Add('valor');
	Inserindo := false;
end;

Obrigado pela resposta.

Foi a primeira coisa que pensei em fazer mais infelizmente não deu certo. veja só o código da Thread:

unit Unit2;

interface

uses
  Classes;

type
  TAdicionar = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation
Uses Unit1;

procedure TAdicionar.Execute;
begin
  while 0 < 1 do begin
    if (Form1.Inserindo = false) then
    begin
      Form1.Inserindo:= True;
      Form1.Lista.Add('TESTE');
      Form1.Inserindo:= False;
    end;
  end;
end;

end.

 

E código de form1

unit Unit1;

interface

uses
  Windows, SysUtils, Forms, Classes, Controls, StdCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  public
    Lista: TStringList;
    Inserindo: Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
  var Pro: TAdicionar; i: Integer;
begin
  for I := 1 to 2 do begin
    ListBox1.Items.Add('Processo de teste Nº '+IntToStr(I)+' iniciado.');
    Pro:= TAdicionar.Create(True);
    Pro.Resume;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Lista:= TStringList.Create;
end;

end.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, eu fiz um teste aqui..

 

criei esta classe implementando a classe TThread:

 

unit Unit2;

interface
	uses
		Classes;
	type
		teste = class(TThread)
			public
				procedure execute; override;
 		procedure adicionar;
 	end;

implementation

uses Unit1;

{ teste }

procedure teste.adicionar;
begin
	Lista.Add('valor');
end;

procedure teste.execute;
begin
 inherited;
 	while(true) do
	begin
		Synchronize(Adicionar);
	end;
end;

end.

na Unit1 eu tenho um objeto do tipo "TStrings" que crio atraves do comando "Lista := TStringLIst.Create", veja:

procedure TForm1.FormCreate(Sender: TObject);
var
	t1, t2 : teste;
begin
	t1 := teste.Create(false);
	t2 := teste.Create(false);
end;
end;

depois criei dois objetos apartir da classe "teste" e não tive problema algum.

 

 

reparei neste seu trecho de código:

 

for I := 1 to 2 do begin
 ListBox1.Items.Add('Processo de teste Nº '+IntToStr(I)+' iniciado.');
 Pro:= TAdicionar.Create(True);
 Pro.Resume;
 end;

e pelo que eu vi, você cria duas instancias de TAdicionar em um único objeto (Pro). Talves seja este o erro, experimente declarar duas variaveis e criar um objeto para cada uma.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, eu fiz um teste aqui..

 

criei esta classe implementando a classe TThread:

 

unit Unit2;

interface
	uses
		Classes;
	type
		teste = class(TThread)
			public
				procedure execute; override;
 		procedure adicionar;
 	end;

implementation

uses Unit1;

{ teste }

procedure teste.adicionar;
begin
	Lista.Add('valor');
end;

procedure teste.execute;
begin
 inherited;
 	while(true) do
	begin
		Synchronize(Adicionar);
	end;
end;

end.

na Unit1 eu tenho um objeto do tipo "TStrings" que crio atraves do comando "Lista := TStringLIst.Create", veja:

procedure TForm1.FormCreate(Sender: TObject);
var
	t1, t2 : teste;
begin
	t1 := teste.Create(false);
	t2 := teste.Create(false);
end;
end;

depois criei dois objetos apartir da classe "teste" e não tive problema algum.

 

 

reparei neste seu trecho de código:

 

for I := 1 to 2 do begin
 ListBox1.Items.Add('Processo de teste Nº '+IntToStr(I)+' iniciado.');
 Pro:= TAdicionar.Create(True);
 Pro.Resume;
 end;

e pelo que eu vi, você cria duas instancias de TAdicionar em um único objeto (Pro). Talves seja este o erro, experimente declarar duas variaveis e criar um objeto para cada uma.

 

 

 

Muito obrigado ! o Synchronize resolveu.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.