Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Thread Cannot call Start on a running or suspended thread hatası
#1
type
 TProductThread = class(TThread)
 private
   FOwnerForm: TForm1;
   FErrorMessage: string; // Hataları saklamak için
 protected
   procedure Execute; override;
   procedure UpdateUI; // UI'yi güncellemek için
   procedure HandleError; // Hataları UI'de göstermek için
 public
   constructor Create(AOwnerForm: TForm1);
 end;

constructor TProductThread.Create(AOwnerForm: TForm1);
begin
 inherited Create(True); // Thread suspended başlar
 FOwnerForm := AOwnerForm;
 FreeOnTerminate := True; // Thread tamamlandığında serbest bırakılır
 FErrorMessage := ''; // Hata mesajını sıfırla
 Start; // Thread başlat
end;


procedure TProductThread.Execute;
var
 JSONObject, JSONObjectCat: TJSONObject;
 DrawArray: TJSONArray;
 JSONValue: TJSONValue;
 I: Integer;
 BasURL: string;
begin
 try
   BasURL := 'https://api.trendyol.com/sapigw/suppliers/918400/products?page=0&size=300&approved=True';
   FOwnerForm.RESTClient1.BaseURL := BasURL;
   FOwnerForm.RESTRequest1.Execute;

   JSONValue := FOwnerForm.RestResponse1.JSONValue;
   if JSONValue = nil then
     raise Exception.Create('Geçerli bir JSON yanıtı alınamadı.');

   JSONObject := TJSONObject(TJSONObject.ParseJSONValue(JSONValue.ToString));
   try
     DrawArray := TJSONArray(JSONObject.FindValue('content'));
     for I := 0 to DrawArray.Count - 1 do
     begin
       with TJSONObject(DrawArray.Items[I]) do
       begin
           isim      := FindValue('title').Value;
           kategoriadi   := FindValue('categoryName').Value;
           barkod        := FindValue('barcode').Value;
           stokkodu  := FindValue('stockCode').Value;
           fiyat     := FindValue('salePrice').Value;
           miktar    := strtoint(FindValue('quantity').Value);
//            drawArraycat  := TJSONArray( FindValue('attributes') );
           if (miktar = 0) and (fiyat='0') then form1.askmem.Lines.Add(stokkodu) else if miktar = 0 then form1.amsmem.Lines.Add(stokkodu)
           else if (form1.kelimeara(stokkodu,form1.asgmem)=False) and (form1.kelimeara(stokkodu,form1.askmem)=False) and (form1.kelimeara(stokkodu,form1.amsmem)=False) then form1.adumem.Lines.Add(stokkodu);
           datayaekle(form1.listview6);
       end;
     end;
   finally
     JSONObject.Free;
   end;

 except
   on E: Exception do
   begin
     FErrorMessage := E.Message; // Hata mesajını kaydet
     Synchronize(HandleError); // Hata durumunda UI'yi bilgilendir
   end;
 end;

 Synchronize(UpdateUI); // UI'yi güncellemek için çağır
end;

procedure TProductThread.UpdateUI;
begin
 // Ana formdaki UI'yi güncelle
 FOwnerForm.Memo1.Lines.Add('İşlem tamamlandı!');
end;

procedure TProductThread.HandleError;
begin
 if FErrorMessage <> '' then
   ShowMessage('Hata: ' + FErrorMessage);
end;



procedure TForm1.StartThread;
begin
 if Assigned(ProductThread) and (not ProductThread.Finished) then
 begin
   ShowMessage('Thread hâlen çalışıyor. Lütfen bekleyin.');
   Exit;
 end;

 ProductThread := TProductThread.Create(Self); // Yeni thread oluştur
end;

Project TrenYolKontrol.exe raised exception class EThread with message 'Cannot call Start on a running or suspended thread'. Hatasını alıyorum. Engelleyemedim...

Amacım şu procedürü thread içine almak

procedure TForm1.ayarurungetir;
var
 JSONObject,JSONObjectcat  : TJsonObject;
 drawArray,drawArraycat   : TJSONArray;
 JSONValue : TJSONValue;
 i,c           : integer;
 aList : TStringlist;
 basurl : string;
 bulunan : boolean;
begin
  try
    askmem.Lines.Clear;
    amsmem.Lines.Clear;
    adumem.Lines.Clear;
    basurl := 'https://api.trendyol.com/sapigw/suppliers/918400/products?page=0&size=300&approved=True';
    RESTClient1.BaseURL := basurl;
    RESTRequest1.Execute;
    jsonvaluec := Restresponse1.JSONValue;
    memo1.Lines.Text := jsonvaluec.ToString;
    finally
    end;
     JSONObject  := TJSONObject(TJSONObject.ParseJSONValue(memo1.Text));
     alist := TStringList.Create;
     try
      aList.Text := memo1.Text;
      JSONObject  := TJSONObject(TJSONObject.ParseJSONValue(aList.Text));
     finally
       FreeAndNil(aList);
     end;
     if JSONObject <> nil then
     try
       drawArray     := TJSONArray( JSONObject.FindValue('content') );
       for I := 0 to drawArray.Count-1 do
       begin
         with TJSONObject( drawArray.Items[i] ) do
         begin
           isim      := FindValue('title').Value;
           kategoriadi   := FindValue('categoryName').Value;
           barkod        := FindValue('barcode').Value;
           stokkodu  := FindValue('stockCode').Value;
           fiyat     := FindValue('salePrice').Value;
           miktar    := strtoint(FindValue('quantity').Value);
           drawArraycat  := TJSONArray( FindValue('attributes') );
           if (miktar = 0) and (fiyat='0') then askmem.Lines.Add(stokkodu) else if miktar = 0 then amsmem.Lines.Add(stokkodu)
           else if (kelimeara(stokkodu,asgmem)=False) and (kelimeara(stokkodu,askmem)=False) and (kelimeara(stokkodu,amsmem)=False) then adumem.Lines.Add(stokkodu);
           datayaekle(listview6);
         end;
       end;
     finally
       JSONObject.Free;
     end;
  memosirala(askmem);
  memosirala(amsmem);
  memosirala(adumem);
end;
Cevapla
#2
(29-11-2024, Saat: 17:55)Jakarta2 Adlı Kullanıcıdan Alıntı:
type
 TProductThread = class(TThread)
 private
   FOwnerForm: TForm1;
   FErrorMessage: string; // Hataları saklamak için
 protected
   procedure Execute; override;
   procedure UpdateUI; // UI'yi güncellemek için
   procedure HandleError; // Hataları UI'de göstermek için
 public
   constructor Create(AOwnerForm: TForm1);
 end;

constructor TProductThread.Create(AOwnerForm: TForm1);
begin
 inherited Create(True); // Thread suspended başlar
 FOwnerForm := AOwnerForm;
 FreeOnTerminate := True; // Thread tamamlandığında serbest bırakılır
 FErrorMessage := ''; // Hata mesajını sıfırla
 Start; // Thread başlat
end;


procedure TProductThread.Execute;
var
 JSONObject, JSONObjectCat: TJSONObject;
 DrawArray: TJSONArray;
 JSONValue: TJSONValue;
 I: Integer;
 BasURL: string;
begin
 try
   BasURL := 'https://api.trendyol.com/sapigw/suppliers/918400/products?page=0&size=300&approved=True';
   FOwnerForm.RESTClient1.BaseURL := BasURL;
   FOwnerForm.RESTRequest1.Execute;

   JSONValue := FOwnerForm.RestResponse1.JSONValue;
   if JSONValue = nil then
     raise Exception.Create('Geçerli bir JSON yanıtı alınamadı.');

   JSONObject := TJSONObject(TJSONObject.ParseJSONValue(JSONValue.ToString));
   try
     DrawArray := TJSONArray(JSONObject.FindValue('content'));
     for I := 0 to DrawArray.Count - 1 do
     begin
       with TJSONObject(DrawArray.Items[I]) do
       begin
           isim      := FindValue('title').Value;
           kategoriadi   := FindValue('categoryName').Value;
           barkod        := FindValue('barcode').Value;
           stokkodu  := FindValue('stockCode').Value;
           fiyat     := FindValue('salePrice').Value;
           miktar    := strtoint(FindValue('quantity').Value);
//            drawArraycat  := TJSONArray( FindValue('attributes') );
           if (miktar = 0) and (fiyat='0') then form1.askmem.Lines.Add(stokkodu) else if miktar = 0 then form1.amsmem.Lines.Add(stokkodu)
           else if (form1.kelimeara(stokkodu,form1.asgmem)=False) and (form1.kelimeara(stokkodu,form1.askmem)=False) and (form1.kelimeara(stokkodu,form1.amsmem)=False) then form1.adumem.Lines.Add(stokkodu);
           datayaekle(form1.listview6);
       end;
     end;
   finally
     JSONObject.Free;
   end;

 except
   on E: Exception do
   begin
     FErrorMessage := E.Message; // Hata mesajını kaydet
     Synchronize(HandleError); // Hata durumunda UI'yi bilgilendir
   end;
 end;

 Synchronize(UpdateUI); // UI'yi güncellemek için çağır
end;

procedure TProductThread.UpdateUI;
begin
 // Ana formdaki UI'yi güncelle
 FOwnerForm.Memo1.Lines.Add('İşlem tamamlandı!');
end;

procedure TProductThread.HandleError;
begin
 if FErrorMessage <> '' then
   ShowMessage('Hata: ' + FErrorMessage);
end;



procedure TForm1.StartThread;
begin
 if Assigned(ProductThread) and (not ProductThread.Finished) then
 begin
   ShowMessage('Thread hâlen çalışıyor. Lütfen bekleyin.');
   Exit;
 end;

 ProductThread := TProductThread.Create(Self); // Yeni thread oluştur
end;

Project TrenYolKontrol.exe raised exception class EThread with message 'Cannot call Start on a running or suspended thread'. Hatasını alıyorum. Engelleyemedim...

Amacım şu procedürü thread içine almak

procedure TForm1.ayarurungetir;
var
 JSONObject,JSONObjectcat  : TJsonObject;
 drawArray,drawArraycat   : TJSONArray;
 JSONValue : TJSONValue;
 i,c           : integer;
 aList : TStringlist;
 basurl : string;
 bulunan : boolean;
begin
  try
    askmem.Lines.Clear;
    amsmem.Lines.Clear;
    adumem.Lines.Clear;
    basurl := 'https://api.trendyol.com/sapigw/suppliers/918400/products?page=0&size=300&approved=True';
    RESTClient1.BaseURL := basurl;
    RESTRequest1.Execute;
    jsonvaluec := Restresponse1.JSONValue;
    memo1.Lines.Text := jsonvaluec.ToString;
    finally
    end;
     JSONObject  := TJSONObject(TJSONObject.ParseJSONValue(memo1.Text));
     alist := TStringList.Create;
     try
      aList.Text := memo1.Text;
      JSONObject  := TJSONObject(TJSONObject.ParseJSONValue(aList.Text));
     finally
       FreeAndNil(aList);
     end;
     if JSONObject <> nil then
     try
       drawArray     := TJSONArray( JSONObject.FindValue('content') );
       for I := 0 to drawArray.Count-1 do
       begin
         with TJSONObject( drawArray.Items[i] ) do
         begin
           isim      := FindValue('title').Value;
           kategoriadi   := FindValue('categoryName').Value;
           barkod        := FindValue('barcode').Value;
           stokkodu  := FindValue('stockCode').Value;
           fiyat     := FindValue('salePrice').Value;
           miktar    := strtoint(FindValue('quantity').Value);
           drawArraycat  := TJSONArray( FindValue('attributes') );
           if (miktar = 0) and (fiyat='0') then askmem.Lines.Add(stokkodu) else if miktar = 0 then amsmem.Lines.Add(stokkodu)
           else if (kelimeara(stokkodu,asgmem)=False) and (kelimeara(stokkodu,askmem)=False) and (kelimeara(stokkodu,amsmem)=False) then adumem.Lines.Add(stokkodu);
           datayaekle(listview6);
         end;
       end;
     finally
       JSONObject.Free;
     end;
  memosirala(askmem);
  memosirala(amsmem);
  memosirala(adumem);
end;

TProductThread.Create içinde Start değil, Resume metodunu çağırmalısınız.

Ayrıca belirtmek isterim ki; bir başka thread içinde iken (örneğimizde sizin TProductThread) ana thread içindeki görsel nesnelere erişim bir çok tahmin edilemez sıkıntılara neden olabilir. Ana thread'e bilgi göndermek, görsel kontrolleri bir şekilde etkilemek istiyorsanız eğer; TThread.Queue metodunu kullanmalısınız. Bu sitede o konu ile ilgili yazılmış bir kaç konu bulabilirsiniz.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#3
Create metodunda tekrar Start kullanmanız problemin kaynağı olarak görülüyor. Fakat bu sorun giderilse dahi Assigned ve Finished gibi kontrol blokları oluşturduğunuz Thread için tekillik sağlamayacak. ProductThread değişkeni, TProductThread sınıfının örneğini temsil ettiği için Assigned bloğu her defasında True olarak yorumlanacaktır. Tüm bunların haricinde @Tuğrul HELVACI bey'in belirttiği hususları da uygulamanın stabil çalışması için sonrasında ayrıca değerlendirmeniz gerekiyor. Mevcut kodlar üzerinden yapılabilecek bir yaklaşım için aşağıdaki kod bloklarında değişiklik yapabilirsiniz.
ProductThread: array of TProductThread;

constructor TProductThread.Create(AOwnerForm: TForm1);
begin
FOwnerForm := AOwnerForm;
FreeOnTerminate := True; // Thread tamamlandığında serbest bırakılır
FErrorMessage := ''; // Hata mesajını sıfırla
inherited Create(False);
end;

procedure TProductThread.UpdateUI;
begin
// Ana formdaki UI'yi güncelle
FOwnerForm.Memo1.Lines.Add('İşlem tamamlandı!');
SetLength(ProductThread, 0);
end;

procedure TProductThread.HandleError;
begin
SetLength(ProductThread, 0);
if FErrorMessage <> '' then
 ShowMessage('Hata: ' + FErrorMessage);
end;

procedure TForm1.StartThread;
begin
if Length(ProductThread) = 0 then
begin
  SetLength(ProductThread, 1);
  ProductThread[0] := TProductThread.Create(Self);
end
else
  ShowMessage('Thread hâlen çalışıyor. Lütfen bekleyin.');
end;
Cevapla
#4
Cevaplarınız için teşekkür ederim. Bu şekilde değiştirdim. İstediğim bu veriler alınırken donma olmamasıydı...


type
  TGetAyarThread = class(TThread)
 private
   FForm: TForm1;
 protected
   procedure Execute; override;
   procedure UpdateUI;
 public
   constructor Create(AForm: TForm1);
 end;

constructor TGetAyarThread.Create(AForm: TForm1);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FForm := AForm;
end;

procedure TGetAyarThread.Execute;
begin
 FForm.ayarurungetir;
 Synchronize(UpdateUI); 
end;

procedure TGetAyarThread.UpdateUI;
begin
 ShowMessage('Veriler alındı!');
end;

procedure TForm1.Image3Click(Sender: TObject);
var
 AyarThread: TGetAyarThread;
begin
 askmem.Lines.Clear;
 amsmem.Lines.Clear;
 adumem.Lines.Clear;
   AyarThread := TGetAyarThread.Create(Self);
   AyarThread.Start; // Thread'i başlat
 memosirala(askmem);
 memosirala(amsmem);
 memosirala(adumem);
end;
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
Photo Errors hatası Kral 6 296 09-11-2024, Saat: 14:19
Son Yorum: mcuyan
  TestFlight Dağıtım (iOS) - Transporter Hatası kajmerantime 7 230 01-11-2024, Saat: 09:23
Son Yorum: RAD Coder
Heart Delphi 12 Decrypt - Encrypt Hatası kajmerantime 10 892 05-07-2024, Saat: 11:28
Son Yorum: mrmarman
  Google play console Android Api hatası lazanya 3 382 01-07-2024, Saat: 19:57
Son Yorum: lazanya
  ClientDataSet Field Not found hatası. mcuyan 0 285 07-06-2024, Saat: 19:57
Son Yorum: mcuyan



Konuyu Okuyanlar: 1 Ziyaretçi