Fórum Liberar Memória de Thread #357667
26/04/2008
0
VThreadCaptions : TMinhaThread;
begin
VThreadCaptions := TMinhaThread.Create(True);
VThreadCaptions.Freeonterminate := true;
VThreadCaptions.Resume;
Com a rotina acima, cria-se uma variável de trhead e, ao término de sua execução, ela é destruída, certo?
Mas, e se o usuário interromper sua execução, o ´terminate´ não ocorreria e ela não seria destruída?
Num teste que fiz aqui, está ocorrendo um erro de memória quando interrompo a execução da trhead e chamo ela novamente. Se dou tempo dela terminar, o erro não ocorrem, ou seja, parece que, não ocorrendo o fim na rotina dentro da trhead, a memória não é liberada e quando ela vai ser executada pela segunda vez, ocorre o erro.
Alguém tem idéia de como resolver isso?
Obrigado.
Armindo
Curtir tópico
+ 0Posts
28/04/2008
Rodc
Poste aqui o código demostrando a pausa e a retomada...
E coloque o código entre as tags ´CODE´ para não perder a formatação:
[code] código
Gostei + 0
28/04/2008
Armindo
[code] código
Certo. Abaixo vai o código.
A trhead é executada no onActivate de cada form.
Quando o operador pressiona ESC em qualquer form, ele (o form) é fechado. Se o caption não sido todo ´escrito´ até o pressionamento do ESC, pois, como pode-se ver abaixo, ele é escrito letra por letra, ocorre uma interrupção na trhead e ela não ´terminate´, certo?
procedure TMinhaThread.execute;
Var
I : Integer;
VTexto : String;
begin
Sleep(300); //espero meio segundo para que o form seja totalmente mostrado na tela. Assim o efeito fica mais notável
Priority := tplower;
VTexto := VCaption; //Vcaption é uma variável da trhead e que recebe valor no onActivate do form
for I := 1 to Length(VTexto) do
begin
VForm.Caption := VForm.Caption + VTexto[I];
sleep(50);
end;
inherited;
end;
Por gentileza, veja se tens uma solução.
Obrigado
Gostei + 0
28/04/2008
Rodc
Veja como usando as Tags do CODE fica mais ´bonito´ e fácil de entender o código postado no forum:
procedure TMinhaThread.execute; Var I : Integer; VTexto : String; begin Sleep(300); //espero meio segundo para que o form seja totalmente mostrado na tela. Assim o efeito fica mais notável Priority := tplower; VTexto := VCaption; //Vcaption é uma variável da trhead e que recebe valor no onActivate do form for I := 1 to Length(VTexto) do begin if Terminated then break; // Verifica se alguém solicitou o encerramento da Thread VForm.Caption := VForm.Caption + VTexto[I]; sleep(50); end; inherited; end;
Gostei + 0
28/04/2008
Armindo
procedure TMinhaThread.execute; Var I : Integer; VTexto : String; begin Sleep(300); //espero meio segundo para que o form seja totalmente mostrado na tela. Assim o efeito fica mais notável Priority := tplower; VTexto := VCaption; //Vcaption é uma variável da trhead e que recebe valor no onActivate do form for I := 1 to Length(VTexto) do begin if Terminated then break; // Verifica se alguém solicitou o encerramento da Thread VForm.Caption := VForm.Caption + VTexto[I]; sleep(50); end; inherited; end;
Obrigado colega pela resposta.
O erro continua, mas não só ocorre se eu exectuar compilando.
Vou dar mais algumas pesquisadas. Se achar a solução, postarei aqui.
Obrigado.
Gostei + 0
28/04/2008
Massuda
Além disso... isso não poderia ser feito usando um TTimer?
Gostei + 0
28/04/2008
Rodc
Armindo, sugiro também fazer a mudança do Caption através de uma função que seja chamada através do método Synchronize().
Gostei + 0
28/04/2008
Massuda
Gostei + 0
28/04/2008
Armindo
Até dá prá fazer com timer, só que aí o form só ficaria liberado para o operador depois que a rotina terminasse. Num caption um pouco grande, isso demoria alguns segundos.
Mas por que você sugeriu o timer em substituição a thread? Só para que esse problema fosse solucionado ou emu sistema teria menos ´peso´ usando o timer?
Obrigado.
Gostei + 0
28/04/2008
Armindo
Tirei, mas não resolveu.
Gostei + 0
28/04/2008
Massuda
Gostei + 0
28/04/2008
Armindo
Vamos supor que tenha um timer (timer1) na aplicação e eu coloque uma determinada rotina no evento onTimer desse timer. Essa aplicação tem um botão que executa uma rotina qualquer quando clicado. No onActivate de um form dessa aplicação, eu coloco timer1.enabled := true.
Até onde eu sei e testei, no exemplo acima, o botão do form só estará disponível para ser clicado quando toda rotina do timer tiver sido executada.
Numa mesma aplicação, só que com a rotina sendo sendo executada por uma thread em vez do timer, o botão ficará disponível assim que o form for carregado. Essa é a vantagem.
Estou errado?
Gostei + 0
28/04/2008
Rodc
Gostei + 0
28/04/2008
Armindo
procedure TMinhaThread.execute;
Var
I : Integer;
VTexto : String;
begin
Sleep(300); //espero meio segundo para que o form seja totalmente mostrado na tela. Assim o efeito fica mais notável
Priority := tplower;
VTexto := VCaption; //Vcaption é uma variável da trhead e que recebe valor no onActivate do form
for I := 1 to Length(VTexto) do
begin
VForm.Caption := VForm.Caption + VTexto[I];
if I = 5 then Self.Close; [b:4f78d9fd4a]este é o teste adicional[/b:4f78d9fd4a]
sleep(50);
end;
inherited;
end;
Nesse teste, na quinta volta ocorre o erro, pois o form está sendo fechado sem que a trhead tenha terminado.
Repito: o problema só ocorre quando executo o programa compilando no Delphi. Se rodar o aplicativo normal (fora do Delphi), não acontece nenhum erro.
Gostei + 0
28/04/2008
Massuda
type TSeuForm = class(TForm) ... SeuTimer: TTimer; private FTitulo: string; FPosicao: Integer; .... procedure TSeuForm.SeuFormCreate(Sender: TObject); begin FTitulo := ´Um titulo qualquer´; FPosicao := 0; Caption := ´´; ... end; procedure TSeuForm.SeuFormActivate(Sender: TObject); begin SeuTimer.Enabled := True; ... end; procedure TSeuForm.SeuFormDeactivate(Sender: TObject); begin SeuTimer.Enabled := False; ... end; procedure TSeuForm.SeuTimerTimer(Sender: TObject); begin Inc(FPosicao); Caption := Caption + FTitulo[FPosicao]; SeuTimer.Enabled := FPosicao < Length(FTitulo); end;
Notei que você usa um intervalo de 50ms entre cada letra... isso dá 20 letras por segundo... o efeito visual fica bom? Acho que muitas pessoas nem perceberão o efeito.
Gostei + 0
28/04/2008
Armindo
O que acontecia era o seguinte: eu mandava o form que receberia o caption como uma variável (VForm). A thread era iniciada e rodava o loop até que todas as letras da variável VCaption, também enviada no chamamento da rotina, fosse escritas. Se, no meio da execução da thread o form fosse fechado, a thread continuaria sendo executada, mas o form já não existiria e isso geraria o erro, pois no onClose, o form é destruído.
Testei seu código Massuda, e realmente funciona com timer. Agora ambas as opções funcionam legal, hehe!
Acho que vou deixar a rotina que utiliza o timer, pois se exige menos da máquina..., é sempre melhor poupar né?.
Obrigado a todos que colaboraram!
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)