Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Sendevorgang blockiert meine Software (https://www.delphipraxis.net/87209-sendevorgang-blockiert-meine-software.html)

skyquaker 25. Feb 2007 08:41


Sendevorgang blockiert meine Software
 
Ich versende in meiner Software mit SMTP meherere Emails mit großen Anhängen. Während ich diese versende, bleibt meine Software jedoch unbenutzbar und wird als "Not Responding" angezeigt. Die Emails werden zwar verschickt, ich kann aber z.B. keinen Pause Knopf betätigen.

Delphi-Quellcode:
procedure TForm1.sndButtonClick(Sender: TObject);
var i : integer;
begin

probar.Visible := true;
probar.Max := globalcnt;


for i := 1 to globalcnt -1 do
begin
 if FileExists('./temporary/'+ExtractFileName(opendiag.filename)+'_'+Inttostr(i)) then
    TIdAttachment.Create(email.MessageParts, './temporary/'+ExtractFileName(opendiag.filename)+'_'+Inttostr(i));
 EMail.Subject := 'Auto generated Message';
 smtp1.Connect;

   try
   smtp1.Send(Email);
   smtp1.Disconnect;
  except on E:Exception do
      Errorlog.Lines.Insert(0, 'ERROR: ' + E.Message);
    end;
   probar.StepIt;
   eMail.MessageParts.Clear;
end;

end;
Was muss ich machen um meine Software auch während des Sendevorgangs benutzbar zu machen?

Matze 25. Feb 2007 08:43

Re: Sende Vorgang blockiert meine Software
 
Hi,

dafür sind Threads ideal. ;)
Diese laufen nebenher und senden die E-Mails im Hintergrund parallel zur Programmausführung.

Aber Achtung: Auf die VCL im Thread immer nur mit Delphi-Referenz durchsuchenSynchronize zugreifen.

Sharky 25. Feb 2007 08:44

Re: Sende Vorgang blockiert meine Software
 
Zitat:

Zitat von skyquaker
...Was muss ich machen um meine Software auch während des Sendevorgangs benutzbar zu machen?

Du musst das versenden der Mails in Threads auslagern. Das ist denke ich die vernünftigste Lösung.

Edit: Warum bekomme ich eigentlich NIE so einen rosten Kasten zu sehen?

skyquaker 25. Feb 2007 08:46

Re: Sendevorgang blockiert meine Software
 
Danke für die schnellen Antworten :thumb:

Ich werd das jetzt mal versuchen mit den Threads.

skyquaker 25. Feb 2007 09:10

Re: Sendevorgang blockiert meine Software
 
Irgendwie schaff ich das nicht. Könnte mir jemand vielleicht ein Beispiel schreiben?

Matze 25. Feb 2007 09:24

Re: Sendevorgang blockiert meine Software
 
Du könntest dir Beispiele oder Luckies Thread-Tutorial ansehen.

Ansonsten zeig uns deinen Ansatz und dann können wir zusammen die Fehler ausmerzen. :)

skyquaker 25. Feb 2007 10:06

Re: Sendevorgang blockiert meine Software
 
Also ich stecke hier fest:

Delphi-Quellcode:
...
type TMailThread = function(mail: TIDMessage; SMTP1: TIDSmTP; Filep: String): Integer;
...
function MailThread(email: TIdMessage; smtp1: TIdSmtp; Filep: String): Integer;
var i: Integer;
begin

for i := 1 to globalcnt -1 do
begin
 if FileExists('./temporary/'+ExtractFileName(filep)+'_'+Inttostr(i)) then
    TIdAttachment.Create(email.MessageParts, './temporary/'+ExtractFileName(filep)+'_'+Inttostr(i));
 EMail.Subject := ExtractFileName(filep)+'_'+Inttostr(i);
 smtp1.Connect;

   try
   smtp1.Send(Email);
   smtp1.Disconnect;
   finally
   eMail.MessageParts.Clear;

end;
end;
end;
...
...
...
procedure TForm1.sndButtonClick(Sender: TObject);
 var ThreadID: DWORD;
  ThreadHandle: THandle;
begin
 ThreadHandle:=CreateThread(nil, 0, TFNThreadStartRoutine(@MailThread),
    nil, 0, ThreadID);

      if ThreadHandle<>0 then CloseHandle(ThreadHandle);
end;
...
Es könnte sein, dass ich alles falsch gemacht habe, deshalb seit net zu streng :wink:

skyquaker 25. Feb 2007 20:39

Re: Sendevorgang blockiert meine Software
 
@mein vorheriger Post

Außerdem weiß ich nicht wie man die Variabeln übergiebt.

C.Schoch 25. Feb 2007 21:13

Re: Sendevorgang blockiert meine Software
 
Hi,
Mit CreateThread übergibst du die Parameter direkt nach der Startfunktion:
Delphi-Quellcode:
ThreadHandle:=CreateThread(nil, 0, TFNThreadStartRoutine(@MailThread),
    {hier}, 0, ThreadID);

      if ThreadHandle<>0 then CloseHandle(ThreadHandle);
end;
wenn du mehr als einen Parameter übergeben willst musst du dir einen record denfineren der die Paramter enthällt.
Warum benutzt du nicht den VCL Thread?
Dort kannst du den Constructor überschreiben und dort die Parameter übergeben.
Auserdem würde ich die eMail Komponente dynamisch innerhalb des Threads erstellen damit ersparst du dir den Syncronisierten Zugriff.

P.S.: Du musst auch warten bis der Thread beendet ist bevor du das Handle schliest, sonst hast du keine Möglichkeit mehr auf den Thread zuzugreifen obwohl er noch läuft.

skyquaker 27. Feb 2007 15:01

Re: Sendevorgang blockiert meine Software
 
Delphi-Quellcode:
unit MailThread;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Controls,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdMessageClient, IdSMTP, StdCtrls, IdIOHandler, IdIOHandlerSocket,
  IdSSLOpenSSL, IdMessage, ComCtrls;

type
  TMailThread = class(TThread)
  private

    procedure MailProc(mail: TIdMessage; path: String; SMTP: TIdSmtp;globalcnt: Integer);
  protected

    procedure Execute(); override;
  public
    constructor Create (CreateSuspended: Boolean; mail: TIdMessage; path: String; SMTP: TIdSmtp;globalcnt: Integer);overload;
  end;

implementation

uses
  atfiles;


var EMail: TIdMessage;
    fPath: String;
    SMTP1: TIdSMTP;
    cnt: Integer;

constructor TMailThread.Create (CreateSuspended : boolean ;mail: TIdMessage; path: String; SMTP: TIdSmtp;globalcnt: Integer) ;
begin
     inherited Create (CreateSuspended) ;
     {Email.Create(nil);}
     {SMTP1.create(nil);}
Email:= TIdMessage.create(Form1);
Smtp1 := TIdSMTP.create(Form1);
  EMail:= mail;
  fPath:= path;
  SMTP1:= SMTP;
  cnt:= globalcnt;
end ;

procedure TMailThread.Execute;
begin
  MailProc(Email, fPath, SMTP1, cnt);
end;

procedure TMailThread.MailProc;
var i: Integer;
begin

for i := 1 to globalcnt -1 do
begin
 if FileExists('./temporary/'+ExtractFileName(path)+'_'+Inttostr(i)) then
    TIdAttachment.Create(mail.MessageParts, './temporary/'+ExtractFileName(path)+'_'+Inttostr(i));
 Mail.Subject := ExtractFileName(path)+'_'+Inttostr(i);
 smtp.Connect;

   try
   smtp.Send(mail);
   smtp.Disconnect;
   finally
   Mail.MessageParts.Clear;
end;
end;



end;

end.
Das ist jetzt meine ThreadUnit, wie binde ich die ein und rufe sie auf? (Das Tutorial hilft mir irgendwie nicht weiter)

EDIT: Ich hab mal versucht es einfach als Procedure aufzurufen (glaub aber das ist total falsch)[kompilieren lässts sich aber]:
Delphi-Quellcode:
TMailThread.Create(true,Email,Opendiag.filename,globalcnt);
Außerdem gibt das immer einen Runtime Error, wenn ich .Create(nil) mache, deshalb hab ich das jetzt zu
Delphi-Quellcode:
Email:= TIdMessage.create(Form1);


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz