Delphi Can

Orjinalini görmek için tıklayınız: Thread Cannot call Start on a running or suspended thread hatası
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
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;
(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.
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;
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;