Isi bilenler bu kodu nasil yazardi?

Başlatan bunalmis, 11 Ocak 2010, 19:35:25

z

Amacimi anlatmam kelimlerle uzun surecek. Asagidaki kodu yazdim.
Calistirdiginizda yapilmak istenen hemen anlasilacak.

Bu amac daha usturuplu gerceklestirilebilirmi?
Programdaki gotolar nasil kaldirilir?

Not: Butonlarin enable ozelligini kullanmak istemiyorum.

procedure TForm1.BASLAClick(Sender: TObject);
label Aradan_Gir,Say;
begin
        if bekle_ then
           begin
              bekle_:=false;
              goto Aradan_Gir;
           end;

        if i<>0 then exit;

Say:    form1.caption:=inttostr(i);
        refresh;
        application.ProcessMessages;

Aradan_Gir:

        while bekle_ do application.ProcessMessages;
        i:=i+1;
        if i<1000 then goto Say;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
        bekle_:=false;
        i:=0;
end;

procedure TForm1.BEKLEClick(Sender: TObject);
begin
        Bekle_:=true;
end;

procedure TForm1.HAZIR_OLClick(Sender: TObject);
begin
        if i>999 then i:=0;
end;
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Yukaridaki kod hic icime sinmiyor. Bu isi nasil daha oturakli yaparim.

Acil cevaplar cok makbule gececek.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

SpeedyX

Aklıma şöyle birşey geldi:
procedure TForm1.BASLAClick(Sender: TObject);
begin
   if (not bekle_) and (i<>0) then
      exit;
   else
      bekle_:=false;
   end;

   repeat
      begin
         Form1.caption := IntToStr(i);
         Refresh;
         repeat
            Application.ProcessMessages;
         until not bekle_
         i:=i+1;
      end;
   until i = 1000;
end;


Tek bir problem var, bekle_ = true ise caption a i yi bir arttırmadan değer yazıyor. Form1.caption := IntToStr(i); kısmı aşağı alınarak durum değiştirilebilinir.

Not: Application.ProcessMessages; satırı uzun işlemlerde programın donmasına engel olamayabilir.

aykuto

Thread kullanmanızı öneririm. Delphi'nin help'inde tthread class'ını incelerseniz nasıl yapmanız gerektiğini anlayacağınızı zannediyorum. Ayrıca Delphide Demos\Threads klasörü altında çok güzel bir örnek var. Onu da inceleyin.

wsxwsx

haklısın ama bu arkadaş bunu anlamaz. anlamak da istemiyor. daha önce en az 3-4 sefer thread konuısunu bildirmişimdir. daha zor şekilde yapmak ve uğraşmak istiyor. işlemleri görsel nesneler ile yapınca thread kullanımı daha da bir zor olur. pek de anlamı olmaz. thread kullanılacaksa , buton, caption gibi nesneler ile işin olmaz. global bazı değişkenleri değiştirirsin. görsel nesneler timer ile müsait birzaman bu global değişkene bakarak captionunu vs.değiştirir. müsait değilse işlemin yine thread içinde devam eder. görsel belirtiler uygun bir zamanda değişir. application..processmessages kullanmak çok fena birşeydir. hele while bekle_ do application.ProcessMessages dediniz mi, cpu kullanımı aşırı yükselir.

z

Alıntı yapılan: "wsxwsx"haklısın ama bu arkadaş bunu anlamaz. anlamak da istemiyor. daha önce en az 3-4 sefer thread konuısunu bildirmişimdir. daha zor şekilde yapmak ve uğraşmak istiyor. işlemleri görsel nesneler ile yapınca thread kullanımı daha da bir zor olur. pek de anlamı olmaz. thread kullanılacaksa , buton, caption gibi nesneler ile işin olmaz. global bazı değişkenleri değiştirirsin. görsel nesneler müsait birzaman bu global değişkene bakarak captionunu filan değiştirir. müsait değilse işlemin yine thread içinde devam eder. görsel belirtiler uygun bir zamanda değişir. applciation.processmessages kullanmak çok fena birşeydir. hele while bekle_ do application.ProcessMessages dediniz mi, cpu kullanımı aşırı yükselir.

Yukaridaki soruya cevap olacak bir ornek verirsen belki anlarim.

Application.processmessages neden CPU yukunu artiriyor anlamadim.

Bu komut sayesinde procesure yada fonksiyon icine girildiginde disarida olup biten olaylarin da ara ara cevaplanmasi icin imkan taniyoruz.

Benim fonksiyonum cagrildiginda duruma gore 1 kac saat (bazen 5 saat) fonksiyon icinden cikilamayacak.

Mevcut yapida program calistiginda bu bir kac saat isi olan fonksiyon calismaya basladiginda zaten benim baska islerle isim olmayacak pur dikkat fonskiyon icinde islemler yapilacak.

Haydi thread kullandim diyelim. Bu bana ne avantaj saglayacak?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

wsxwsx

http://www.speedyshare.com/files/20288408/demo.zip
burada prensibi anlatan bir örnek var.
Timer olayına yazılacak kod ile , thread içinde olup bitenleri dış dünyaya göstermiş oluyoruz.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  label2.Caption := inttostr(th.sayac);
  led.Visible := not led.Visible;
end;


thread kullanırsan o sırada formu sürükleyip başka işler de yapabileceksin. bir yandan hesap kitap yaparken başka bir yandan gelen bilgileri istifleyebileceksin.  diğer taraftan başka bir thread  (bekçi diyelim) acaba alet yerinde mi cihazı söküp başka bir yere takmış olabilirler mi diye onu kontrol edecek.  gül gibi geçinip gidecekler. hepsi beraber çalışacak. sleep(500) yazılınca bu esnada başka işlem yapılmayacak anlamına gelmiyor. diğer threadler 500ms lik zaman ayrılmış demektir.  Birde sleepEx() fonksiyonu vardır. vaktinden önce sonlandırılabilir.  yani 500ms beklerken süre dolmadan bazı işlemler tamamlanırsa hemen sonlanaibliyor. threat içinde bazı olaylar tanımlamışsan sleep yazsan bile bu olaylar tetikleniyor. ancak bu olayı thread içinde oluşturduğun başka bir thread tetiklemesi gerekebilir.

yukarıdaki link bozuk galiba yeniledim.
http://www.speedyshare.com/files/20288408/demo.zip

z

Anladigim kadariyla PC de yazacagim program tek bir isle değil de bir kac isle ugrasacak olsaydi ve basla dedigimde uc isi de ayni zamanda baslatsaydi o zaman bu dediginiz yontem isime yarardi.

Aksi halde bu 3 isi tek ismis gibi tek fonksiyon catisi altinda toplamam gerekirdi ve program bayagi karmasik  ve anlasilirligi zor olurdu.

Thread kullaninca bu 3 isi bagimsiz islermis gibi dusunup programlarini yazmak kolay ve anlasilir olurdu. (Ben bunu anladim)

Ben hala islemleri bir kac saat surecek bir uygulamayi neden thread kullanarak yapayim anlamadim.

Program calisirken telefon calar acil bir is olur programi bekletmek gerekebilir diye bir tusa basilip basilmadigini application.processmessages ile kontrol ediyorum. Basildi ise de bir dongu icinde haydi devam edelim komutunu bekliyorum. Bu esnada da windows gene diger islemlerini yapiyor.

Bunda ne gibi bir yanlislik goruyorsun anlamadim.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

wsxwsx

senin yöntemde programın donmasını önlemek için , application.processmessages kullanmak gerekir. o da  yapılan işi aksatır. yavaşlatır. Hızlı bir bilgisayarın  olsa dahi yavaş kalır.

Fakat ayrı bir thread kullandın diyelim. threadi sonlandırmak için  yine bir buton kullanılabilir. örneğin buton basılınca global bir değişken  değişir. thread döngü içinde buna bakar. gerekirse kendini sonlandırır. if son then self.terminate gibi.

eğer thread kullanırsan birkaç saat sürecek işi bilgisayar 1-2 dakikada tamamlayabilir.

Normalde ayrı uygulama açtığımızda aslında ayrı bir thread başlamış oluyor. bu yüzden bir programın donması  diğerini etkilemiyor.  form içinde ayrı thread kullanmadan uzun bir döngü yaparsak program donmuş olur. istenmeyen bir durumdur. gerekli yerlere application.processmessages ekleyerek vaziyeti kurtarmaya çalışırız. ancak bir döngü içinde sürekli bunu kullanırsak işler aksar. hiç olmazsa saniyede bir filan kullanılır. durum daha az kötü olur.

controller

@bunalmis

yukarıdaki gibi bir programı başlattığınızda çalışan ilk ve tek thread "ui (user interface) thread" dir. bu thread kullanıcı ile sizin programınız arasındaki iletişimi sağlayan uygulama pencerenizi yönetir. eğer siz uzun sürecek işlemi oluşan bu ilk ui thread içine yazarsanız yaptığınız işlem süresince uygulama pencereniz kullanıcıya cevap veremeyecektir. siz bunu engellemek için application.processmessages gibi bir çözüme başvurmuşsunuz. ancak burada doğru olan uzun sürecek işlemlerin, işlem çok basit dahi olsa ui thread den bağımsız olarak ayrı bir thread de yapılmasıdır. konu başlığında bahsettiğiniz "işi bilenler" bu şekilde yapmaktadırlar.
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

z

Uygulamamda isin 5 saat gibi uzamasina neden olan durum yazilim değil kumanda edilen mekanik cihazin yavas olmasi.

Fonksiyon icine bir girildimi saatlerce calisiyorsa zaten hangi kodu isletirsek isletelim CPU kullanimi max olacaktir. Bunda application.processmessages in etkisi yok.

Asagidaki kodun icindeki for dongusu fonksiyonun uzun zaman calismasini simule etmek icin eklendi. Kodlamayi state machine mantigi ile yazdim ve sorunsuz kullaniyorum.

Thread konusu da bu tartismadan sonra bir acik kapi ve gerektiginde kullanirim artik.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Calistir: TButton;
    BEKLE: TButton;
    procedure CalistirClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BEKLEClick(Sender: TObject);
  private
    { Private declarations }
    ShowKey : Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  basladi,bekle_:boolean;
  i:integer;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
        bekle_:=false;
        basladi:=false;
end;

procedure TForm1.CalistirClick(Sender: TObject);
var i:integer;
begin
        if (basladi or bekle_) then exit;
        Basladi:=true;
        for i:=0 to 10000 do
           begin
              form1.caption:=inttostr(i);
              refresh;
              repeat
                Application.ProcessMessages;
              until not bekle_
           end;
        Basladi:=false;
end;


procedure TForm1.BEKLEClick(Sender: TObject);
begin
        If not basladi then Bekle_:=true;
        Bekle_:=Not Bekle_;
        If bekle_ then Bekle.Caption:='Devam Et'
        else Bekle.Caption:='Bekle'

end;

end.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Alıntı yapılan: "controller"@bunalmis

yukarıdaki gibi bir programı başlattığınızda çalışan ilk ve tek thread "ui (user interface) thread" dir. bu thread kullanıcı ile sizin programınız arasındaki iletişimi sağlayan uygulama pencerenizi yönetir. eğer siz uzun sürecek işlemi oluşan bu ilk ui thread içine yazarsanız yaptığınız işlem süresince uygulama pencereniz kullanıcıya cevap veremeyecektir. siz bunu engellemek için application.processmessages gibi bir çözüme başvurmuşsunuz. ancak burada doğru olan uzun sürecek işlemlerin, işlem çok basit dahi olsa ui thread den bağımsız olarak ayrı bir thread de yapılmasıdır. konu başlığında bahsettiğiniz "işi bilenler" bu şekilde yapmaktadırlar.

Bu tartismadan sunu anladim eger dogruysa sizlere hak veriyorum.

Eger telefon caldiginda programi beklemeye alirsam program hala cpu dan buyuk ilgi talep ediyor. Halbuki beklemeye alindiginda internette gezinmek isteyebilirim.

Benim uyguladigim mantikta internet gezintim yavaslayacak.
Thread kullanirsam ve programi beklemeye alirsam internette hizli gezinecegim.

Dogrumu?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

controller

bu konuyu uzunca açıklamaya şu an vaktim yo ancak sizin burada yaptığınız işletim sisteminin akışına boş yere karışmak oluyor. ben işletim sisteminin yerinde olsam beklemedeki application.processmessages işlemi için "kardeşim zaten hiç bir iş yapmadan bekliyorsun, ne diye benim işime karışıyorsun" derdim. sizin yaptığınız kulağı tersten tutmak gibi.
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

wsxwsx

en klas programı da yapsan, donan bir program kötüdür.  mesela windowsun ses kaydedicisi var.  bu ufak program mis gibi . hiç donmuyor.  bir yandan ses çalıyor veya kaydediyor. müsait zamanda ekrana ufak grafik gibi birşey çiziyor.  ara sıra sıkışıp donduğunu hiç görmedim. Pencereyi sürüklerken sadece görsel kısım kesintiye uğruyor. Bunun sebebi, sesle ilgili işlemlerin, ses kartından gelen bilgilerin arka planda başka threadler tarafından yürütülmesidir.