Jak stworzyć wątki do idSMTP idPOP3 idMessage?

0

Witam serdecznie!

Szukałem na forum i nie znalazłem konkretnej odpowiedzi na mój problem. Była jedna, ale autor nie podał rozwiązania - dogadał się z kimś na gg, wątek był sprzed kilku lat... Szukam i szukam i nie mogę znaleźć.

Piszę program do przesyłania i odbierania plików - przez skrzynkę pocztową.

Chcę aby program mógł ściągać kilka maili na raz z różnych skrzynek pocztowych
lub ewentualnie wysyłać i odbierać jednocześnie maile z załączonymi plikami.

Oczywiście trzeba to zrobić za pomocą wątków i teraz moje pytanie jest takie:

Nie wystarczy się odwołać do komponentu położonego np: na Form1 za pomocą Synchronize... bo to by nie miało sensu, kilka wątków by się odwoływała do jednego komponentu przykładowo do idSMTP, jeden by mu przypisał takie ustawienia, a drugi inne, poza tym komponenty te "zawieszają" działanie aplikacji, dlatego pozostaje stworzenie dynamicznych komponentw idSMTP, idPOP3 i idMessage dla każdego wątku osobno.

Skupmy się przykładowo na komponencie idSMTP:

Tworzę klasę TThread

procedury Create, Destroy, Execute, MyOnTerminate.

W jakim miejscu w wątku wywołać Create komponentu idSMTP?
I w jakim miejscu w wątku zwalniać go metodą Free po zakończeniu zadania, bo nigdzie tego nie mogę znaleźć. Jeśli utworzę dynamicznie komponent w wywołaniu procedury Create wątku, to jak się potem odwoływać do tego komponentu, jak go zwolnić przy zakończeniu wątku - a może Delphi robi to automatycznie przy zakończeniu wątku...???

Czy może stworzyć go w procedurze Execute? Stworzenie idSMTP, wykonanie roboty i zwolnienie... Ale też problem wywala błąd: Nieodpowiednie dojście okna, czy coś w tym stylu. No i znów jak się do niego odwoływać, powiedzmy z procedury MyOnTerminate, żeby poinformowała który wątek o jakim numerze zakończył pracę...

Jak zwolnić uruchomiony wątek np o numerze 2 klikając na Button z Form1...

Bardzo proszę o jakieś sugestię, może w formie kawałka kodu dotyczącego utworzenia dyn. komponentu w wątku i jego zwolnienie.

Z góry dziękuję i pozdrawiam:).

Deklaruję przykładowo wątek:

TSendMail = class(TThread)
  private
     FNazwaPliku: string; // nazwa pliku z konfiguracją dla idPOP3 (adres serwera, nazwa, hasło itd).
     Fnr: integer; // numer wątku;     
procedure MyOnTerminate(Sender: TObject); // obsługa zdarzenia OnTerminatre
  public
    constructor Create(nr: integer; NazwaPliku: String); // konstruktor dla klasy
    destructor Destroy; override; // destruktor dla klasy
  protected
    procedure Execute; override;
  end;

constructor TSendMail.Create(nr: integer; NazwaPliku: string);
begin
  inherited Create(False); // wywołanie konstruktora klasy bazowej
  {coś tam}
end;

destructor TSendMail.Destroy;
begin
  {coś tam}
  inherited;
end;
procedure TSendMail.MyOnTerminate(Sender: TObject);
begin
  Form1.Caption:='Wątek Zakończony';
end;

procedure TSendMail.Execute;
begin
  FreeOnTerminate:=True;

 wywołanie procedury z TSendMail...
end;
0

Twórz i zwalniaj komponenty Indy w wątku głównym.
Twórz dodatkowy wątek w momencie podjęcia akcji, niszcz po jej zakończeniu.
Akcją niech będzie Connect, Send i Disconnect.

Możesz wykorzystać mój komponencik:
Jak uzyskać tryb nieblokujący dla metod blokujących
jakoś w ten sposób:

  TSendMail = class
  private
    FIdSMTP: TIdSMTP; //IdSMTP tworzone i niszczone wraz z klasą TSendMail
    FSendTask: TNonBlockingTask; //wątek
    FMsg: TIdMessage; //wiadomość do wysłania
    procedure SendTaskProc; //zadanie wykonywane przez wątek (Connect, Send)
    procedure SendTaskStop(Sender: TObject; Completed: Boolean; Exc: Exception); //obsługa zdarzenia zakończenia wątku
  public
    constructor Create;
    destructor Destroy; virtual;

    procedure Send; //metoda uruchamiająca wysyłanie
  end;

implementation

constructor TSendMail.Create;
begin
  FSendTask := TNonBlockingTask.Create(nil, SendTaskProc);
  FSendTask.OnStop := SendTaskStop;
  FIdSMTP := TIdSMTP.Create;
  FIdSMTP.Host := ...
  FIdSMTP.Port := ...
end;

destructor TSendMail.Destroy;
begin
  try
    FSendTask.Kill;
  finally
    try
      FIdSMTP.Free;
    finally
      inherited;
    end;
  end;
end;

procedure TSendMail.Send;
begin
  FMsg := ...
  FSendTask.Run;
end;

procedure TSendMail.SendTaskProc;
begin
  FIdSMTP.Connect;
  FIdSMTP.Send(FMsg);
end;

procedure TSendMail.SendTaskStop(Sender: TObject; Completed: Boolean; Exc: Exception);
begin
  FIdSMTP.Disconnect;
  if Completed then
    ShowMessage('Ukończono')
  else if Exc = nil then
    ShowMessage('Anulowano')
  else
    ShowMessage('Wystąpił wyjątek:'#13#10'''' + Exc.Message + '''');
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1