thread form donma sorunsalı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
seci20

thread form donma sorunsalı

Mesaj gönderen seci20 »

Kolay gelsin ustalarım. Theread kullanımdığımda bazı yerlerde threadın bitmesini beklemesi gerekli ama waitfor yada waitforsingleobject kullandığımda form tamamıyla donuyor bunun önüne nasıl geçebilirim ? Nette bir çok araştırma yaptım geneli repeat yada while ile yapmışlar ama zaten o zaman threadın anlamı kalmıyor anladığım kadarı ile bu sorunu nasıl aşabilirim şimdiden çok teşekkür ederim...
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: thread form donma sorunsalı

Mesaj gönderen ertank »

Merhaba, thread kodunuzu paylaşabilir misiniz?
ercan_elo_bil
Üye
Mesajlar: 26
Kayıt: 11 Tem 2014 11:13

Re: thread form donma sorunsalı

Mesaj gönderen ercan_elo_bil »

merhaba,

ilgili yazdığınız procedure leri execute procedurunün icerisinde kullanıyorsunuz değil mi?
Garbage Collector, Delphi çöp üretmez çöpü bulup temizlemeye asla gerek yoktur... :D
seci20

Re: thread form donma sorunsalı

Mesaj gönderen seci20 »

ercan_elo_bil yazdı: 22 Oca 2018 11:43 merhaba,

ilgili yazdığınız procedure leri execute procedurunün icerisinde kullanıyorsunuz değil mi?
tabikide hocam su sekılde

Kod: Tümünü seç

type
  Threadim = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;
  
  
  
  
  procedure Threadim.Execute;
begin
sleep(20000);
end;

procedure TFrmMain.Button1Click(Sender : TObject);
begin
  Threadim:= TThread.Create;
  showmessage('');    // bu mesaj direk geliyor....
  end;

ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: thread form donma sorunsalı

Mesaj gönderen ertank »

Merhaba,

Özetle yapmaya çalıştığınız yanlış ve bu yöntem ile istediğinizi elde edemezsiniz.

Thread açıklaması bir yerde şöyle yapılabilir: Normalde uzun sürecek ve/veya kullanıcı ara yüzünü donduracak (yanıt vermez hale getirecek) işlemlerin arka planda ayrı bir uygulama içinde çalışıyormuş gibi kullanımıdır.

Ayrı bir uygulama içinde çalışıyormuş gibi olduğu için sizin uygulamanız thread çalışmasına müdahale edemez. Nitekim thread çalıştıran bir uygulama da thread'i kapatmamalı, sadece kapanması için sinyal göndermeli. Ya da belirli zamanlarda/koşullarda iletişimde bulunmalı ve işleyişine başka türlü karışmamalıdır.

Eğer sizin istediğiniz işlem bittiği zaman mesaj gösterilsin ise kodunuzu normal bir prosedür içine yazın ve bu prosedürü çağırın

Kod: Tümünü seç

unit Unit1;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure Calis();
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Calis();
begin
  Sleep(20000);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  Calis();
  ShowMessage('');
end;

end.
Yukarıdaki şekilde istediğiniz davranışı elde edebilirsiniz. Ancak bu durumda uygulamanız yanız vermez duruma düşer. Eğer uygulamanızın yanıt vermez duruma düşmesini istemiyor iseniz bu defa ilgili kodunuzu Windows işletim sistemine halen sorun olmadığı ve uygulamanızın düzgün çalıştığına dair bilgilendirecek aşağıdaki yönteme benzer şekilde yazabilirsiniz.

Kod: Tümünü seç

procedure TForm1.Calis2();
const
  Limit = 20000;
var
  Sayac: Cardinal;
begin
  Sayac := GetTickCount();
  while (GetTickCount() - Sayac) < Limit do
  begin
    Sleep(1000);
    Application.ProcessMessages();
  end;
end;
Bu örnekte yine kullanıcı arayüzü 1 saniyelik gecikmeler ile fare/klavye vb olaylara yanıt verecektir. Yani duraksamalı çalışıyor hissi verecektir.

Eğer hiç takılma olmasın istiyor iseniz bu noktada thread kullanmalısınız. Tabi thread kullandığınız zaman sizin yönteminiz yine çalışmaz hale gelecektir. Thread bittiğinden haberdar olmak istiyor iseniz TThread.OnTerminate() olayını aşağıdaki şekilde kullanabilirsiniz.

Kod: Tümünü seç

unit Unit1;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ThreadBitti(Sender: TObject);
  public
    { Public declarations }
  end;

  TMyThread = class(TThread)
  protected
    procedure Execute(); override;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TMyThread.Execute;
begin
  Sleep(20000);
end;

procedure TForm1.ThreadBitti(Sender: TObject);
begin
  ShowMessage('');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  AThread: TMyThread;
begin
  AThread := TMyThread.Create(True);
  AThread.FreeOnTerminate := True;
  AThread.OnTerminate := ThreadBitti;
  AThread.Start();
end;

end.
Cevapla