读书人

关于多线程。该怎么解决

发布时间: 2012-08-16 12:02:15 作者: rapoo

关于多线程。
unit uSendThread;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdMessage, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient,
IdSMTPBase, IdSMTP, StdCtrls;

type
TSendEmlThread = class(TThread)
private
{ Private declarations }
ASmtp: TIdSMTP;
AMsg: TIdMessage;
FAMemo: TMemo;
FAEmailAddr: string;

procedure DoSend;
procedure SetAMemo(const Value: TMemo);
procedure SetAEmailAddr(const Value: string);
protected

procedure Execute; override;
published
property AMemo: TMemo read FAMemo write SetAMemo;
property AEmailAddr: string read FAEmailAddr write SetAEmailAddr;
constructor Create(smtpHost, smtpUser, smtpPwd, subj, body,ContentType,Charset, emalAddr, Sender, FromAddr: string;
OtherParas: string; authType:TIdSMTPAuthenticationType; AMemo: TMemo);
end;

implementation

{
Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,

Synchronize(UpdateCaption);

and UpdateCaption could look like,

procedure TSendEmlThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;

or

Synchronize(
procedure
begin
Form1.Caption := 'Updated in thread via an anonymous method'
end
)
);

where an anonymous method is passed.

Similarly, the developer can call the Queue method with similar parameters as
above, instead passing another TThread class as the first parameter, putting
the calling thread in a queue with the other thread.

}

uses main;

{ TSendEmlThread }

constructor TSendEmlThread.Create(smtpHost, smtpUser, smtpPwd, subj, body,
ContentType, Charset, emalAddr, Sender, FromAddr, OtherParas: string;
authType: TIdSMTPAuthenticationType; AMemo: TMemo);
begin
try
Inc(frmMain.ThreadQty);
ASmtp := TIdSMTP.Create(nil);
ASmtp.Host := smtpHost;
ASmtp.Username := smtpUser;
ASmtp.Password := smtpPwd;
ASmtp.AuthType := authType;

AMsg := TIdMessage.Create(nil);
Amsg.Subject := subj;
AMsg.Body.Text := body;
AMsg.ContentType := ContentType;
Amsg.CharSet := Charset;
AMsg.Recipients.Add.Address := emalAddr;
AMsg.Sender.Address := FromAddr;
AMsg.Sender.Name := Sender;

Self.AEmailAddr := emalAddr;
Self.AMemo := AMemo;
FreeOnTerminate := True;
except
on E: exception do
ShowMessage(e.Message);
end;
inherited Create(false);
end;

procedure TSendEmlThread.DoSend;
begin
try
// connect to smtp server
try
if Asmtp.Connected then ASmtp.Disconnect();
ASmtp.Connect;
//Application.ProcessMessages;
except
on E: exception do
begin
if Assigned(FAMemo) then
FAMemo.Lines.Add('Error connecting to server, Msg:' + e.Message);


end;
end;
// send email
//Application.ProcessMessages;
try
ASmtp.Authenticate;
ASmtp.Send(AMsg);
//Application.ProcessMessages;
if Assigned(FAmemo) then
FAMemo.Lines.Add('Send to ' + Self.AEmailAddr + ' successfully');
if ASmtp.Connected then
ASmtp.Disconnect();
except
on E: exception do
begin
if Assigned(FAMemo) then
FAMemo.Lines.Add('Send to ' + Self.AEmailAddr + ' failed, Msg:' + e.Message);
end;
end;
finally
Dec(frmMain.ThreadQty);
frmMain.UpdateStatus;
{Application.ProcessMessages;
if ASmtp.Connected then
ASmtp.Disconnect();
}
//Self.Free;
end;

end;

procedure TSendEmlThread.Execute;
begin
{ Place thread code here }
Synchronize(DoSend);
end;

procedure TSendEmlThread.SetAEmailAddr(const Value: string);
begin
FAEmailAddr := Value;
end;

procedure TSendEmlThread.SetAMemo(const Value: TMemo);
begin
FAMemo := Value;
end;

end.


===============================================================

麻烦大牛帮看下。 代码有什么问题。 好像网络阻塞。
程序假死。




[解决办法]
procedure TSendEmlThread.Execute;
begin
{ Place thread code here }
DoSend
end;

...
finally
Dec(frmMain.ThreadQty);
Synchronize(DoUpdateStatus);
...

procedure TSendEmlThread.DoUpdateStatus;
begin
frmMain.UpdateStatus

end;

读书人网 >.NET

热点推荐