Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Thread Terminate ederken Destroy Kullanmak
#1
S.a 
Thread Sınıfımda 
Execute içerisinde 

TStringList *YedeklemePeryodu = new TStringList();

Değişkenler Tanımlayıp Kullanıyorum
Bu Pointer Değişkenler While Değişkeni içerisinde Değiller
Birkez Oluşturuyorum


Execute nin Sonlanmaması için 


while (1)
{
//VeriTabanı Sunucusuna Bağlanmak, Yedeklemek, Yediği Sıkıştırmak, Mesaj Atmak için yazdığım kodları buraya yazdım

}

bir kaç kez yedekledikten sonra
bir süre sonra excute içerisindeki kodlarımın threadın çalışmasını durdurduğunu farkettim


şu anda hangi kodun threadı durdurduğunu bilemiyorum

Sınıfın Suspended=true Etmek istediğimde  
Thread Error: Erişim engellendi (5)
Hatası Verdiğini gördüm

yapmak istediğim hatanın kaynağını bulana kadar 
bir timer içerisinde bir kaç saatte bir
Thread Suspended=true edip 
Eğer Hata Thread Error: Erişim engellendi (5) ise
Thread Terminate edip Sonra Free edip
Tekrar Thread Tekrar Oluşturmak ancak
TStringList *YedeklemePeryodu = new TStringList(); ile oluşturduğum Değişkenler Bellekten Silinir mi Yoksa Bellekte Yer Kaplamaya Devam mı eder onu bilmiyorum silinmiyorsa 
Normal Classlarda ki Destroy Metodunu Thread nasıl kullanabilirim
Cevapla
#2
Benim thread ile thread durumunu kontrol ettigim timer aynı uygulama içinde çalışıyor
Sadece sonlandırırken thread içinde oluşturdugum pointer ların bellekten nasıl temizleyebilirim onu çözemedim thread destroy metodunu bulamadım
Cevapla
#3
Hocam Uygulamada veritabanı olarak firebird embedded kullandım Tek bağlantı oluyor ve program da sistemde aynı anda sadece tek bir adet çalıştırılabiliyor

 thread içine Başka uygulamadan mesaj göndermeyi bilmiyorum
hatayı aldığım anda uygulamayı komple kapatsam uygulama oluşturdugum bütün pointerlar da bellekten silinmiş olur mu
Sonra uygulamayı tekrar açarım
Cevapla
#4
(19-01-2019, Saat: 10:30)theSinan Adlı Kullanıcıdan Alıntı: S.a 
Thread Sınıfımda 
Execute içerisinde 

TStringList *YedeklemePeryodu = new TStringList();

Değişkenler Tanımlayıp Kullanıyorum
Bu Pointer Değişkenler While Değişkeni içerisinde Değiller
Birkez Oluşturuyorum


Execute nin Sonlanmaması için 


while (1)
{
//VeriTabanı Sunucusuna Bağlanmak, Yedeklemek, Yediği Sıkıştırmak, Mesaj Atmak için yazdığım kodları buraya yazdım

}

bir kaç kez yedekledikten sonra
bir süre sonra excute içerisindeki kodlarımın threadın çalışmasını durdurduğunu farkettim


şu anda hangi kodun threadı durdurduğunu bilemiyorum

Sınıfın Suspended=true Etmek istediğimde  
Thread Error: Erişim engellendi (5)
Hatası Verdiğini gördüm

yapmak istediğim hatanın kaynağını bulana kadar 
bir timer içerisinde bir kaç saatte bir
Thread Suspended=true edip 
Eğer Hata Thread Error: Erişim engellendi (5) ise
Thread Terminate edip Sonra Free edip
Tekrar Thread Tekrar Oluşturmak ancak
TStringList *YedeklemePeryodu = new TStringList(); ile oluşturduğum Değişkenler Bellekten Silinir mi Yoksa Bellekte Yer Kaplamaya Devam mı eder onu bilmiyorum silinmiyorsa 
Normal Classlarda ki Destroy Metodunu Thread nasıl kullanabilirim

Merhaba,

Bence 2 tane ciddi sorun var:

1. Thread içinde hata var ve bu yüzden thread'in Execute fonksiyonu kırılıyor. Thread'in ürettiği hatayı yakalayan bir mekanizmanız olmadığı için de hatayı görmüyorsunuz. Ama siz hatayı tespit etmekten ziyade, hatayı nasıl görmezden gelir ve bana yarattığı sorunları ortadan kaldırabilirim diye hareket ediyorsunuz. Sorununuzun çözümü çok zor değil. Execute fonksiyonunun tamamını try/except bloğu arasına alın ve except kısmında hatayı bir OutputDebugString ile IDE'ye gönderin. Kod bloğu aşağıdaki gibi olmalıdır:

try
 // Thread içindeki kodunuz
except
  on E: Exception do
  begin
    OutputDebugString(PChar(E.Message));
  end;
end;

Bu tavsiye hatayı yakalamak için verilmiş bir tavsiyedir. Müşteriye vereceğiniz sürümde bu kodun olması bence doğru değil.

2. thread.Suspended := True Delphi'nin eski sürümlerinde olan ve daha sonra terkedilen bir yöntemdir. Thread'lerin geçici olarak durdurulması, bekletilmesi, sonlandırılması gibi konular biraz bilgi ve dikkat gerektiren konulardır. Benim size tavsiyem bu konuda biraz daha araştırma yapmanızdır. @Tuğrul HELVACI'nın kişisel sitesinde Thread'ler konusunda oldukça güzel yazıları var. Bunları okumanızı ve iyice anladıktan sonra thread kullanmanızı tavsiye ederim.

İyi çalışmalar
Cevapla
#5
(21-01-2019, Saat: 07:31)Bahadir.Alkac Adlı Kullanıcıdan Alıntı:
(19-01-2019, Saat: 10:30)theSinan Adlı Kullanıcıdan Alıntı: S.a 
Thread Sınıfımda 
Execute içerisinde 

TStringList *YedeklemePeryodu = new TStringList();

Değişkenler Tanımlayıp Kullanıyorum
Bu Pointer Değişkenler While Değişkeni içerisinde Değiller
Birkez Oluşturuyorum


Execute nin Sonlanmaması için 


while (1)
{
//VeriTabanı Sunucusuna Bağlanmak, Yedeklemek, Yediği Sıkıştırmak, Mesaj Atmak için yazdığım kodları buraya yazdım

}

bir kaç kez yedekledikten sonra
bir süre sonra excute içerisindeki kodlarımın threadın çalışmasını durdurduğunu farkettim


şu anda hangi kodun threadı durdurduğunu bilemiyorum

Sınıfın Suspended=true Etmek istediğimde  
Thread Error: Erişim engellendi (5)
Hatası Verdiğini gördüm

yapmak istediğim hatanın kaynağını bulana kadar 
bir timer içerisinde bir kaç saatte bir
Thread Suspended=true edip 
Eğer Hata Thread Error: Erişim engellendi (5) ise
Thread Terminate edip Sonra Free edip
Tekrar Thread Tekrar Oluşturmak ancak
TStringList *YedeklemePeryodu = new TStringList(); ile oluşturduğum Değişkenler Bellekten Silinir mi Yoksa Bellekte Yer Kaplamaya Devam mı eder onu bilmiyorum silinmiyorsa 
Normal Classlarda ki Destroy Metodunu Thread nasıl kullanabilirim

Merhaba,

Bence 2 tane ciddi sorun var:

1. Thread içinde hata var ve bu yüzden thread'in Execute fonksiyonu kırılıyor. Thread'in ürettiği hatayı yakalayan bir mekanizmanız olmadığı için de hatayı görmüyorsunuz. Ama siz hatayı tespit etmekten ziyade, hatayı nasıl görmezden gelir ve bana yarattığı sorunları ortadan kaldırabilirim diye hareket ediyorsunuz. Sorununuzun çözümü çok zor değil. Execute fonksiyonunun tamamını try/except bloğu arasına alın ve except kısmında hatayı bir OutputDebugString ile IDE'ye gönderin. Kod bloğu aşağıdaki gibi olmalıdır:

try
 // Thread içindeki kodunuz
except
  on E: Exception do
  begin
    OutputDebugString(PChar(E.Message));
  end;
end;

Bu tavsiye hatayı yakalamak için verilmiş bir tavsiyedir. Müşteriye vereceğiniz sürümde bu kodun olması bence doğru değil.

2. thread.Suspended := True Delphi'nin eski sürümlerinde olan ve daha sonra terkedilen bir yöntemdir. Thread'lerin geçici olarak durdurulması, bekletilmesi, sonlandırılması gibi konular biraz bilgi ve dikkat gerektiren konulardır. Benim size tavsiyem bu konuda biraz daha araştırma yapmanızdır. @Tuğrul HELVACI'nın kişisel sitesinde Thread'ler konusunda oldukça güzel yazıları var. Bunları okumanızı ve iyice anladıktan sonra thread kullanmanızı tavsiye ederim.

İyi çalışmalar

Hocam Tavsiyeniz için Teşekkür Ederim
Ben Kodlama Yaparken Yazdığım Bütün Kodları Her Zaman
Try Catch Blokları Arasına Yazıyorum
Thread Execute İçerisinde Yazdığım kodlarda Try Catch
Komutları içerisinde Yazdım
Catch ile Yakaladığım Hatayı log dosyasına kayıt ediyorum
Program Çalışma esnasında Bir Hata Meydana Gelirse Kırılmayı önlemek adına Bu şekilde Yapıyorum
Program Yedeklemek istenilen VeriTabanın Olduğu  Servera Bağlantı kurma , yedekalma, Yedeği Zipleme, Rapor Oluşturma , Mail ve Sms Göndermek için Yazdığım Kodları ayrı ayrı Fonksiyonlar içerisinde Tanımladım bu fonksiyonlar içerisinde Grafik işlemleri yok

Execute Fonksiyonu içerisinde de Bu Fonksiyonları çalıştırıyorum
Program Tek Seferlik çalışmadığından Execute nin içerinde Kodları sonsuz döndüğe almak için

While(1)
{
//buraya kodlarımı yazıyorum
}

hemen hata vermiyor
bir süre sonra Executenin içerisindeki Kodların çalışmadığı görüyorum
bütün fonksiyonlarım execute dahil içerisinde try catch var
log dosyasına baktığımda catch yakaladığı bir hata göremiyorum
Bellekten taşma mı oluyor şu ana kadar sebebini bulamadım
çözene kadar geçici olarak uygulamaya bir timer koydum
timer 4 saat te bir Thread Suspended ini True edip Tekrar False ediyor eğer hata alırsa
ikinci bir exe oluşturdum o exeyi çalıştırıyor
ve yedekleme uygulamasını kapatıyor
sonra ikinci exe bir süre sonra yedekleme uygulamasını yeniden başlatıyor
sorunu asıl kaynağında çözmem gerektiğini biliyorum
çözene kadar öğrenmek istediğim
yedekleme uygulamasında Pointer Değişkenler var yedekleme uygulaması kapandığında pointerlarda bellekten silinir mi
Cevapla
#6
Merhaba,

Söyleceklerimi maddeler şeklinde yazayım:

- Ben C++ değil Delphi kullandığınızı düşünmüştüm. Eğer C++ kullanıyorsanız (muhtemelen Rad Studio C++ kullanıyorsunuz, yoksa bu forumda sormak biraz mantıksız olurdu) CodeGuard kullanın. Böylece bellek taşması, geçersiz bellek işlemleri gibi sorunları çözebilirsiniz.

- Her fonksiyonu try/catch aralığına almak büyük yanlış. Eğer Java veya C# kullanıyorsanız bu kabul edilebilir, ama C++ ve Delphi gibi dillerde try/catch'in performansa etkisi çok yüksektir. Bu yüzden de gerekmedikçe try/catch kullanmak doğru değil (bu kişisel görüşüm).

- Her fonksiyonu try/catch aralığına alıyorsanız o zaman fonksiyonlarınızın hiçbiri void değil, hepsi bir değer döndürüyor. Gerçekten de bir değer döndürmesi gereken fonksiyonlarınız da referansla değer döndürüyor demektir. Bu da kod yazmayı ve okumayı inanılmaz zorlaştırır ve işin doğrusu C programlama yöntemidir (C dilinde try/catch yok). Size tavsiyem bundan vazgeçmeniz ve hata yönetimi konusunu biraz daha araştırmanızdır.

- Eğer try/catch aralığnda olmasına rağmen catch kısmında hata yakalama kodlarınız (loglama kodlarınız) çalışmıyorsa çok ciddi bir bellek hatası var demektir. Eğer şanslıysanız bu düzenli olarak aynı yerde hata veriyordur. Bunun da çözümü thread kodunuz içine geçici olarak log fonksiyonları eklemek. Yani

void __fastcall TMyThread::Execute()
{
 AddToLog(L"Execute", L"Start of function");
 try
 {
   AddToLog(L"Execute", L"Calling function 1");
   function1();

   AddToLog(L"Execute", L"Calling function 2");
   function2();

   AddToLog(L"Execute", L"End of try");
 }
 catch(Exception *E)
 {
   AddToLog(L"Execute", E->Message);
 }
 AddToLog(L"Execute", L"End of function");
}


AddToLog fonksiyonunu iki parametreli düşündüm: Fonksiyon adı, log mesajı. Kodları ona göre yazdım. Kodu IDE'de yazıp denemedim, sadece bilgi amaçlı yazdım. "Start of function", "End of try" ve "End of function" loglarını özellikle ekledim. Size de asıl tavsiyem bu olacak zaten. Thread sınıfı içindeki her fonksiyona (constructor ve destructor dahil) bu şekilde log kodu eklemenizi tavsiye ederim. (Aslında bunları compiler directive'leri arasına almanız çok daha güzel olur ama o başka bir konu)

Alıntı:yedekleme uygulamasında Pointer Değişkenler var yedekleme uygulaması kapandığında pointerlarda bellekten silinir mi?

Bu göründüğü kadar basit bir soru değil Smile

- Pointer değişken dediğiniz tam olarak nedir? Örneğin private kısımda tanımladığınız bir integer değişkenin adresini tutan pointer sorun değil. 
- int *A = new int; dediğiniz zaman sorun. Ama burada da söylenecek çok şey var. Modern işletim sistemleri (Windows Vista ve sonrası) bellek yönetiminde yeterince başarılılar. Sizin sistemden aldığınız ve geri vermediğiniz bellek program sonlandığında işletim sistemi tarafından geri alınır (Ama eskiden böyle değildi. Daha doğrusu bunu iddia etmesine rağmen o kadar da başarılı değildi). O yüzden, eğer programın açılışında aldığınız ve program boyunca ihtiyaç duyduğunuz bir bellek alanından bahsediyorsak, her ne kadar kişisel olarak onaylamasam da, bunu da geri vermeseniz olur. Zaten program kapanınca işletim sistemi alacak. 
- Programın içinde bir döngüde aldığınız bellek geri verilmeden sürekli alınıyorsa burada işler çok kısa zamanda sarpa sarabilir. Bir süre sonra programınız yönetemeyeceği kadar çok bellek ayırmış olacak ve çökecektir. Çökmese bile sistemin kaynaklarınız müsrifçe kullanmış olacaksınız. Unutmayın, işletim sistemi sadece sizin programınızı çalıştırmıyor.
- Sonuç olarak, sorumluluk sahibi bir programcı olarak, sistemden aldığınız belleği, işiniz bittiği zaman (işinizin ne zaman biteceğine siz karar vereceksiniz, belki de performans için elinizde tutmak isteyebilirsiniz) sisteme geri vermelisiniz. 

Yazdıklarınızdan anladığım kadarıyla sizin asıl sorununuz memory corruption. Örnek vermek gerekirse, 10 elemanlık bir dizi açmışsınız, ama 11. elemana veri yazmışsınız. Ya da string'leri char * ile yönetiyorsunuz ama bir yerde NULL pointer hesabını yanlış yaptığınız için bellek taşması olmuş. O kadar yazdım, ama sonuçta yine ilk yazdığım maddeye geri döneceğim. CodeGuard bu tür hataları yakalamak için size yardımcı olacaktır Smile

İyi çalışmalar
Cevapla
#7
hocam

Thread içinde
thread aralığındaki bazı fonksiyonlarım değer döndürmüyor void olarak tanımladım
hatayı da anaforma tanımladım bir fonksiyona catch içerisinden gönderiyorum o fonksiyonda hatayı log dosyasına kayıt ediyor

String tuttuğum değişkenlerde hiç char * kullanmadım
thread içerisindeki döngüde yeni değişken tanımlaması yok
yine thread excute nin ilk başında tanımladığım değişkenleri döngü içerisinde sadece değer ataması yapıyorum
kodları şimdiye kadar hep try catch fonkiyonları içerisinde tanımlıyorum alışkanlık mı acemilik mi bilemiyorum
programın kırılmasından ise yavaş çalışması daha iyi diye düşüncesindeyim
hem hataları loglamayıda kolaylaştırıyor

Rad Studio C++ İle Yazıyorum
CodeGuard daha önce hiç kullanmadım
Nerden Başlayacağım hakkımda bir fikrim şimdilik yok
araştıracağım
Yardımlarınız için Allah Razı Olsun
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Thread içinde CoInitialize(nil) ve CoUninitialize serdar 6 1.067 22-08-2023, Saat: 09:50
Son Yorum: yhackup
  Thread Socket (Yardım) hkeskin 1 1.387 11-07-2023, Saat: 12:47
Son Yorum: delphiman
  Thread pool mantığı nasıl kurulmalı ? mrmarman 12 3.162 16-12-2021, Saat: 20:45
Son Yorum: Tuğrul HELVACI
  Destroy edememe KUNTAY 6 1.383 14-12-2021, Saat: 00:26
Son Yorum: KUNTAY
Question Bu thread kullanımı doğrumu ? seci20 0 667 05-09-2021, Saat: 12:55
Son Yorum: seci20



Konuyu Okuyanlar: 1 Ziyaretçi