Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 3 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Thread Durdurma
#1
Amaç: Her 15 dakikada bir belirlenen bir işi yapması istenen bir thread'in Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol API'leri vasıtası ile kodlanması ve uygulamanın ana thread'inden istenilen herhangi bir zamanda thread'den çıkılmasını sağlamak. (Elbette Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol kullanmadan)

Not: 20 puan değerindedir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
unit Unit4;

interface

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

type
 TForm4 = class(TForm)
   Label1: TLabel;
   Button1: TButton;
   Button2: TButton;
   procedure Button2Click(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form4: TForm4;
 cikis:bool;

implementation

{$R *.dfm}
function saydir(param: Pointer) : DWORD;
var
i:integer;
begin
;
for I := 0 to  1000  do
begin
Form4.Label1.Caption:=IntTostr(i);   //labelde 1den bine kadar yazdırıyoruz
if(cikis=true)then break;
Sleep(10);
end;


end;


procedure TForm4.Button1Click(Sender: TObject);
var
id : Dword;
begin

 cikis := false;
 CreateThread(nil, 0, @saydir, 0, 0, id);
  button1.Enabled:=false;
end;

procedure TForm4.Button2Click(Sender: TObject);
begin
cikis := true;
button1.Enabled :=true;
end;
procedure TForm4.Timer1Timer(Sender: TObject);//timer'in intervali 900000
var
id : Dword; 
begin
 cikis :=false;
 CreateThread(nil, 0, @saydir, Label1, 0, id);
  button1.Enabled:=false;
end;
end.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#3
(08-11-2017, Saat: 17:23)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
unit Unit4;

interface

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

type
 TForm4 = class(TForm)
   Label1: TLabel;
   Button1: TButton;
   Button2: TButton;
   procedure Button2Click(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form4: TForm4;
 cikis:bool;

implementation

{$R *.dfm}
function saydir(param: Pointer) : DWORD;
var
i:integer;
begin
;
for I := 0 to  1000  do
begin
Form4.Label1.Caption:=IntTostr(i);   //labelde 1den bine kadar yazdırıyoruz
if(cikis=true)then break;
Sleep(10);
end;


end;


procedure TForm4.Button1Click(Sender: TObject);
var
idBig Grinword;
begin

 cikis := false;
 CreateThread(nil, 0, @saydir, 0, 0, id);
  button1.Enabled:=false;
end;

procedure TForm4.Button2Click(Sender: TObject);
begin
cikis := true;
button1.Enabled :=true;
end;

end.

Uyanıkça bir çözüm yoluna gitmişsiniz. Ama istediğim bu değil. Sleep ya da SleepEx ile toplam 15 dakika bekleyeceksiniz. Parça parça değil. Sorunun amacı buna bina edilmiş zaten.

Ayrıca bir thread içinden bir başka thread(main thread) içindeki paylaşımlı alanlara erişir iken dikkatli olmakta fayda var. Bu amaçla, TThread.Queue, TThread.Synchronize metodlarını kullanmak ya da başka senkronizasyon nesneleri ile paylaşımlı kodu sarmalamak gerekir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
Hocam Event Nesneleri kullanarak mı yapacağız.  Cry
My name is nobody.
WWW
Cevapla
#5
(08-11-2017, Saat: 22:15)ismailkocacan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlHocam Event Nesneleri kullanarak mı yapacağız.  Cry

İstediğiniz kadar Event kullanabilirsiniz. Ama bekleme kodunu Event üzerinden WaitForSingleObject/WaitForMultipleObjects ya da Event.WaitFor ile yapmayacaksınız. Sleep ya da SleepEx dememin önemli bir nedeni var. Açıklar isem, soru ve sorunun kazandırması gerekenleri yani amacı yitiririz.

Düşünüldüğü kadar kolay bir soru değil. Ama o kadar da zor değil Wink

Küçücük bir ip ucu vereyim ki ilerlemek kolay olsun. APC
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#6
Thread'imiz içinde Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile Timer oluşturmalıyız. 
Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile bu timer'ın ayarlarını yapmalıyız.
Sonrasında Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile beklemeye geçmeliyiz. 
SleepEx'i istediğimi zaman sonlandırabilmek için 2. parametresini True yapmalıyız.
SleepEx'ten çıkmak için Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile thread'imize tanımladığımız bir Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol'yi (Asynchronous Procedure Call) gönderebiliriz.


procedure TTimerThread.Execute;
var
  timerHandle: THandle;
 larg_int : LARGE_INTEGER;
begin
 timerHandle := CreateWaitableTimer(nil, False, 'WaitableTimer');
 larg_int.QuadPart := -9000000000;
 SetWaitableTimer(timerHandle, Int64(larg_int), 900000, @Callback, nil, False);
 while not Terminated do
   SleepEx(INFINITE, True);
 CloseHandle(timerHandle);
end;

procedure Callback(P: Pointer; H, L: LongWord); stdcall;
begin
  // Burada periyodik olarak yapılacak işlemler yazılacak
end;

SetWaitableTimer'ın 2. parametresi Timer'ın ne zaman başlayacağını belirtir ve 100 NANO saniye hassasiyettedir. Dilediğiniz bir tarih-saati belirtebileceğiniz gibi bizim örneğimizde olduğu gibi eksi değer kullanılırsa fonksiyon çağrıldıktan ne kadar zaman sonra Timer'ın tetikleneceği belirtilmiş olur. (Bizden istenen 15 dakika olduğu için yukarıdaki değer girilmiştir)
SetWaitableTimer'ın 3. parametresi ise periyottur. Bu parametre ise saniye cinsindendir ve 15 dakikaya göre ayarlanmıştır. 4. parametre ise Timer tetiklendiğinde çağrılacak fonksiyonu belirtir. Örnek Callback fonksiyonu yukarıda verilmiştir.

Threadimizin kullanımına örnek için bir form, üzerinde 2 buton ile deneme yapabiliriz:
type
 TForm1 = class(TForm)
   btnStart: TButton;
   btnStop: TButton;
   Memo1: TMemo;
   procedure btnStartClick(Sender: TObject);
   procedure btnStopClick(Sender: TObject);
 private
   TT: TTimerThread;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure APC(Param: Cardinal); stdcall;
begin
 //
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
 TT := TTimerThread.Create(True);
 TT.FreeOnTerminate := True;
 TT.Start;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
 QueueUserAPC(@APC, TT.Handle, 0);
 TT.Terminate;
end;
There's no place like 127.0.0.1
WWW
Cevapla
#7
(10-11-2017, Saat: 00:19)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlThread'imiz içinde Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile Timer oluşturmalıyız. 
Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile bu timer'ın ayarlarını yapmalıyız.
Sonrasında Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile beklemeye geçmeliyiz. 
SleepEx'i istediğimi zaman sonlandırabilmek için 2. parametresini True yapmalıyız.
SleepEx'ten çıkmak için Linkleri Görebilmeniz İçin Giriş yap veya Üye Olile thread'imize tanımladığımız bir Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol'yi (Asynchronous Procedure Call) gönderebiliriz.


procedure TTimerThread.Execute;
var
  timerHandle: THandle;
 larg_int : LARGE_INTEGER;
begin
 timerHandle := CreateWaitableTimer(nil, False, 'WaitableTimer');
 larg_int.QuadPart := -9000000000;
 SetWaitableTimer(timerHandle, Int64(larg_int), 900000, @Callback, nil, False);
 while not Terminated do
   SleepEx(INFINITE, True);
 CloseHandle(timerHandle);
end;

procedure Callback(P: Pointer; H, L: LongWord); stdcall;
begin
  // Burada periyodik olarak yapılacak işlemler yazılacak
end;

SetWaitableTimer'ın 2. parametresi Timer'ın ne zaman başlayacağını belirtir ve 100 NANO saniye hassasiyettedir. Dilediğiniz bir tarih-saati belirtebileceğiniz gibi bizim örneğimizde olduğu gibi eksi değer kullanılırsa fonksiyon çağrıldıktan ne kadar zaman sonra Timer'ın tetikleneceği belirtilmiş olur. (Bizden istenen 15 dakika olduğu için yukarıdaki değer girilmiştir)
SetWaitableTimer'ın 3. parametresi ise periyottur. Bu parametre ise saniye cinsindendir ve 15 dakikaya göre ayarlanmıştır. 4. parametre ise Timer tetiklendiğinde çağrılacak fonksiyonu belirtir. Örnek Callback fonksiyonu yukarıda verilmiştir.

Threadimizin kullanımına örnek için bir form, üzerinde 2 buton ile deneme yapabiliriz:
type
 TForm1 = class(TForm)
   btnStart: TButton;
   btnStop: TButton;
   Memo1: TMemo;
   procedure btnStartClick(Sender: TObject);
   procedure btnStopClick(Sender: TObject);
 private
   TT: TTimerThread;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure APC(Param: Cardinal); stdcall;
begin
 //
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
 TT := TTimerThread.Create(True);
 TT.FreeOnTerminate := True;
 TT.Start;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
 QueueUserAPC(@APC, TT.Handle, 0);
 TT.Terminate;
end;

Ellerinize sağlık. Puanınızı verdim sevgili üstadım. Umarım bu soru, araştırmaya ve APC'yi öğrenmeye; yumuşak ve kontrollü bir şekilde thread durdurmayayı öğrenmeye vesile olabilmiştir. Hedeflenen, APC kavramı ve QueueUserAPC apisi idi.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#8
Asıl ben teşekkür ederim. Benim için çok öğretici oldu. Açıkçası QueueUserAPC'yi daha önce hiç duymamıştım Sad  Bu vesile ile öğrendim.

Bu arada; bu soruya cevap vermemde bana en çok yardımcı olan sayfayı belirtmeden geçemeyeceğim:
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Smile
There's no place like 127.0.0.1
WWW
Cevapla
#9
(10-11-2017, Saat: 09:51)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlAsıl ben teşekkür ederim. Benim için çok öğretici oldu. Açıkçası QueueUserAPC'yi daha önce hiç duymamıştım Sad  Bu vesile ile öğrendim.

Bu arada; bu soruya cevap vermemde bana en çok yardımcı olan sayfayı belirtmeden geçemeyeceğim:
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Smile

Rica ederim üstad. Aslında çeşitli zamanlarda çeşitli vesileler ile ilgili API'den biraz bahsetmiştim Smile 2 örnek bulabildim kısaca şimdilik Smile

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#10
Bu Access violation bölümü baklava gibi bişi oldu, tadından yenmiyor Smile
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter





Konuyu Okuyanlar: 1 Ziyaretçi