Tüm Platformlar için Hızlı Uygulama Geliştirme --->    Kitabımız...      Delphi

Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 2.5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Asenkron Procedure
#1
Merhabalar,

Basit bir procedurumu aynı anda asenkron olarak onlarca oluşturmak fakat takip etmek istemiyorum işlem birince infilak etsin kendiliğinden bu işlem için thread uygun mudur ?

   TMyNotify = class(TThread)
  public
   constructor Create(const Intent, Title, Text,UserToken,Id: string);
 end;




constructor TMyNotify.Create(const Intent, Title, Text, UserToken, Id: string);
begin
 inherited Create(true);
 FreeOnTerminate := true;

   ////  Benim kodlarım

  resume;

Bu şekilde bir kod yazdım şimdilik çalışıyor gibi Smile
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#2
işi bittiğinde infilak etmesini istiyorsan interface kullanabilirsin...
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#3
(12-12-2017, Saat: 13:01)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Olişi bittiğinde infilak etmesini istiyorsan interface kullanabilirsin...

Peki interface asenkron çalışır mı ,
Örneğin interfaceim içerisindeki proceduru çalıştırdığımda procedurun bitmesini bekler miyim ?
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#4
Neden asenkron çalışmasın?

Sınıfı tanımlarken çoklu tip kullanabilirsin, tuğrul beyin yazılarındaki örnekleri inceleyebilirsin.

type
  ICellat = interface
    public
    // vesair
  end;

type
  TMyNotify = class(TThread, ICellat)
    // vesair
  end;

gibi...
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#5
(12-12-2017, Saat: 13:46)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlNeden asenkron çalışmasın?

Sınıfı tanımlarken çoklu tip kullanabilirsin, tuğrul beyin yazılarındaki örnekleri inceleyebilirsin.

type
  ICellat = interface
    public
    // vesair
  end;

type
  TMyNotify = class(TThread, ICellat)
    // vesair
  end;

gibi...

Bilmiyorum o sebepten sordum üstad Smile Buraları kurcalıyordum bende.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Peki üstteki kullanımımda ne gibi sorun olabilir ?
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#6
Thread'ler tam da "saldım çayıra mevlam kayıra" için kullanılabilir. Ancaak! nasıl bir kod yazacağına göre durum değişebilir Wink Konuyu biraz daha detaylandırabilirsen sanırım daha faydalı olabiliriz.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#7
(12-12-2017, Saat: 14:16)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlThread'ler tam da "saldım çayıra mevlam kayıra" için kullanılabilir. Ancaak! nasıl bir kod yazacağına göre durum değişebilir Wink Konuyu biraz daha detaylandırabilirsen sanırım daha faydalı olabiliriz.

Tamda öyle bir iş için threada başvurdum Smile
Senaryo şöyle MySQL'imde ortak bir Notification tablosu var, Diğer bazı tablolardaki, hareketlerde trigger ile otomatik bu tabloya kayıt atıyorum, içerisindeki fieldin biri de okundu , okunmadı bilgisi.

Bu tabloya düşen kayıtların hiç bekletmeksizin kullanıcılara Push edilmesini istiyorum. İşlemi de Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol Push ettikten sonra eğer mesaj başarılı ise okundu bilgisini güncelleyerek devam ediyorum.

Ama sıradaki diğer bildirimi göndermem için push işleminin bitmesi gerekiyor ki sıradaki bildirimi atayım.

Ben bu işlemi beklemeden var ise bildirim 10 kişiye birden atayım o procedure kendi içinde işi bitince tabloyu update edip kapasın yok olsun.

Zaten bu halde bile kullandığı ram 3mb dolaylarında Smile

Şu an kullandığım yapı şu şekilde,

   
TMyNotify = class(TThread)
 public
   constructor Create(const Intent, Title, Text,UserToken,Id: string);
 end;




constructor TMyNotify.Create(const Intent, Title, Text, UserToken, Id: string);
const apikey = 'AIzaSyDJ0---------mXdZuQ';
var
  SStream  : TStringStream;
  Response : TMemoryStream;
  t        : TStringList;
  Request  : TclHttpRequest;
  Cont,Data,Json:TJSONObject;

begin
 inherited Create(true);
 FreeOnTerminate := true;

  Data    := TJSONObject.Create;
  Cont    := TJSONObject.Create;
  Data.AddPair('IntentCode',Intent);
  Data.AddPair('ContentTitle',Title);
  Data.AddPair('ContentText',Text);
  Data.AddPair('NotificationId',Id);
  Cont.AddPair('data',Data);
  Cont.AddPair('to',UserToken);

  t         := TStringList.Create;
  Response  := TMemoryStream.Create;
  Request   := TclHttpRequest.Create(nil);
  SStream   := TStringStream.Create(Cont.ToJSON);
    try
      try
          Request.RequestStream := SStream;
          Request.Header.ContentType   := 'application/json';
          Request.Header.ExtraFields.Add('Authorization:key='+apikey)   ;
          Request.Header.ContentLength := IntToStr(SStream.Size);
          DMod.firebase.post('https://fcm.googleapis.com/fcm/send', Request,Response);
          Response.Position := 0;
          t.LoadFromStream(Response);
          Log(t.Text);

          Json := TJSONObject.Create;
           try
             Json.Parse(BytesOf( t.Text ), 0);
             if (Trim(Json.GetValue('success').ToString) = '1') then
             begin
                with DMod.Query do
                begin
                  Close;
                  SQL.Clear;
                  SQL.Add('UPDATE `notifications` SET delivered=1 where id=:id');
                  ParamByName('id').AsInteger := StrToInt(id);
                  Execute;
                end;
             end;
           finally
            Json.DisposeOf;
           end;
      except on E: Exception do
      end;
    finally
       t.Free;
       Response.Free;
       Request.Free;
       SStream.Free;
       Cont.DisposeOf;
    end;
Resume;
end;



procedure SendNotify(const Intent, Title, Text,UserToken,Id: string);
var Notify:TMyNotify;
begin
  Notify := TMyNotify.Create(Intent, Title, Text,UserToken,Id);
end;

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#8
Muhtemelen Tuğrul Üstad size daha detaylı bilgi verecektir bu konuda ama ben başlangıç olarak şunu söyleyebilirim: TThread kullanıyorsanız kodlarınız Execute prosedürü içerisinde olmalı. Create içinde kodlarınızı yazarsanız aslında Thread kullanmamış gibi olursunuz.
There's no place like 127.0.0.1
WWW
Cevapla
#9
(12-12-2017, Saat: 14:53)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlMuhtemelen Tuğrul Üstad size daha detaylı bilgi verecektir bu konuda ama ben başlangıç olarak şunu söyleyebilirim: TThread kullanıyorsanız kodlarınız Execute prosedürü içerisinde olmalı. Create içinde kodlarınızı yazarsanız aslında Thread kullanmamış gibi olursunuz.

Kodu bu şekilde düzenledim ama bir süre sonra, exe çalışıyor ama kapatamıyorum Big Grin

   TMyNotify = class(TThread)
   private
   FIntent, FTitle, FText, FUserToken, FId : String;
  protected
   procedure Execute; override;
 public
//    constructor Create(const Intent, Title, Text,UserToken,Id: string);
   constructor Create;

   property Intent    : String read FIntent;
   property Title     : String read FTitle;
   property Text      : String read FText;
   property UserToken : String read FUserToken;
   property Id        : String read FId;
 end;
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla
#10
Evet SimaWB'in dediği gibi; constructor Create içinde hâla main thread'in etki alanındasın. Ancak ve ancak, Execute sırasında bu etki alanının dışında olursun(Yani başka bir thread içinde).

Bir kaç hatırlatma daha yapmak istiyorum. Bu bir genel kural aslında. Bir thread içinde veritabanı erişimi söz konusu olacak ise; her zaman yeni bir veritabanı erişim nesnesi create edin. Ve thread içinde bu connection nesnesini kullanacak başka nesneleri create edin. Yani senin örneğinde bir query oluyor bu. Neden ?

Çünkü; yeni oluşturduğunuz thread uygulama içindeki A connection'ını kullanarak veri güncellemeye çalışır iken; uygulamanın ana thread'i A connection'ını kullanarak herhangi bir tablodan veri çekmeye çalışır ise ne olur Wink

Pek iyi olmaz değil mi Smile Bu ve buna benzer pek çok nedenden ötürü, thread'lerin içinden veritabanı erişimlerinde yeni bir connection kullanılması çok önemlidir.

 Şimdi bu husustan bahsettiğimize göre, bu seferde Execute altına yazdığın kodları görelim ki neden takılıyor bunu tespit etmeye çalışalım.

Bu arada, TThread.CreateAnonymousThread 'i de kullanabilirsin, illa bir sınıf tanımlamana gerek yok.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter





Konuyu Okuyanlar: 1 Ziyaretçi