首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

关于多线程。该怎么解决

2012-08-16 
关于多线程。unit uSendThreadinterfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.V

关于多线程。
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;

热点排行