多线程pop3收信问题 (收信没问题,程序退出时报错) ???(100分)

  • 主题发起人 主题发起人 jimyho
  • 开始时间 开始时间
J

jimyho

Unregistered / Unconfirmed
GUEST, unregistred user!
我用TThread 封装过
SakPOP,NMPOP3,idPOP3(indy),
收信没问题,程序退出时却老报错:
"raised exception class EWin32Error
with message A Win32 API function failed"
百思不解... 程序大概如下:
type
TClsSakPOP = class(TThread)
private
FPOP:TSakPOP;
//FMSG:TSakMsg;
FstbAccount:TStatusBar;
FprbAccount:TProgressBar;
FlvRcpList:TListView;
protected
procedure Execute;
override;
public
constructor Create(RunNow:boolean;{POP:TSakPOP;MSG:TSakMsg;}
stbAccount:TStatusBar;prbAccount:TProgressBar;
lvRcpList:TListView);
destructor Destroy;override;
//-- 连接服务器
function ConnectServer(NewConnection:boolean):boolean;
//-- 连接成功之后,完成一次收当前Mail,并打印的功能
procedure RetireveEmails;//--test
procedure AddRcpInfoToLog(FileName,RefNo,Page,FaxTime, ReceiveTime,FaxFrom:string);
procedure GetParamsFormSubject(S:string;out RefNo,From,ReceivedTime:string);
//-- After Retrieve 一封 Mail 事件
procedure SakPOPAfterRetrieve(Sender: TObject);
//-- 正在收信事件
procedure SakPOPRetrieveProgress(Sender: TObject;
Percent: Word);
procedure SakPOPError(Sender: TObject;
Error: Integer;
Msg: String);
procedure SakPOPBeforeRetrieve(sender: TObject;
MsgIndex: Word);
end;

implementation
constructor TClsSakPOP.Create(RunNow:boolean;{POP:TSakPOP;MSG:TSakMsg;}
stbAccount:TStatusBar;prbAccount:TProgressBar;
lvRcpList:TListView);
begin
inherited Create(RunNow);
FPOP:=TSakPOP.Create(nil);
FPOP.Host:='xxx.xxx.xxx';
FPOP.Port:='110';
FPOP.UserId:='xxx';
FPOP.UserPasswd:='xxx';
FstbAccount:=stbAccount;
FprbAccount:=prbAccount;
FlvRcpList:=lvRcpList;
FPOP.OnBeforeRetrieve:= SakPOPBeforeRetrieve;
FPOP.OnAfterRetrieve:= SakPOPAfterRetrieve;
FPOP.OnRetrieveProgress:=SakPOPRetrieveProgress;
FPOP.OnError:= SakPOPError;
end;
//-----
destructor TClsSakPOP.Destroy;
begin
FPOP.free;
FPOP:=nil;
FstbAccount:=nil;
FprbAccount:=nil;
FlvRcpList:=nil;
inherited Destroy;
end;
//----
procedure TClsSakPOP.Execute;
var
sPath:string;
begin
FreeOnTerminate:=True;
ConnectServer(True);
if (not FPOP.Connected) then
exit;
sPath:=ExtractFilePath(Application.Exename)+ 'DownTiff/';
RetireveEmails;
end;

//-- 连接服务器
function TClsSakPOP.ConnectServer(NewConnection:boolean):boolean;
begin
//-- 连接服务器
end;
//== 把发送时的信息添加到 lstLog
procedure TClsSakPOP.AddRcpInfoToLog(FileName,RefNo,Page,FaxTime,
ReceiveTime,FaxFrom:string);
begin
//...
end;
//----
procedure TClsSakPOP.GetParamsFormSubject(S:string;out RefNo,From,ReceivedTime:string);
begin
//...
end;

//-- After Retrieve 一封 Mail 事件
procedure TClsSakPOP.SakPOPAfterRetrieve(Sender: TObject);
begin
FstbAccount.Panels[0].text := 'This Mail Retrieved ..';
FprbAccount.Visible:=False;
end;

//-- 正在收信事件
procedure TClsSakPOP.SakPOPRetrieveProgress(Sender: TObject;
Percent: Word);
begin
FprbAccount.Position := Percent;
end;

procedure TClsSakPOP.SakPOPError(Sender: TObject;
Error: Integer;
Msg: String);
begin
FstbAccount.Panels[0].text := 'Error';
FstbAccount.Panels[1].text := Msg;
end;

procedure TClsSakPOP.SakPOPBeforeRetrieve(sender: TObject;
MsgIndex: Word);
begin
FprbAccount.Top:= 1;
FprbAccount.Left:= 1;
FprbAccount.Visible:=True;
FprbAccount.Position := 0;
end;

//-- 连接成功之后,完成一次收当前Mail,并打印的功能
procedure TClsSakPOP.RetireveEmails;
var
FMSG:TSakMsg;
iMsgNo,iMsgsMaxCount:integer;
begin
iMsgsMaxCount:=FPOP.MsgsCount;
if iMsgsMaxCount > 0 then
begin
for iMsgNo:= 1 to iMsgsMaxCountdo
begin
FMSG:=TSakMsg.Create(nil);
FprbAccount.Position := 0;
FstbAccount.Panels[1].text :='Retrieving ' + inttostr(iMsgNo) + ' of total ' + inttostr(iMsgsMaxCount);
try
FPOP.RetrieveMessage(iMsgNo,FMSG);
except
FstbAccount.Panels[0].text :='Abort,Disconnect';
FstbAccount.Panels[1].text :='Retrieve The ' + inttostr(iMsgNo) + ' Mail Fail';
FMSG.Free;
FPOP.Quit;
exit;
end;
//..保存并打印
//..
FMSG.AttachedFiles.Clear;

FMSG.Free;
end;
end
else
FstbAccount.Panels[1].text :='No Mail Found';
FPOP.quit;
FstbAccount.Panels[0].text :='Disconnect';
FstbAccount.Panels[1].text :='';
end;

end.

 
//-- 连接成功之后,完成一次收当前Mail,并打印的功能
procedure TClsSakPOP.RetireveEmails;
var
FMSG:TSakMsg;
iMsgNo,iMsgsMaxCount:integer;
begin
iMsgsMaxCount:=FPOP.MsgsCount;
if iMsgsMaxCount > 0 then
begin
for iMsgNo:= 1 to iMsgsMaxCountdo
begin
FMSG:=TSakMsg.Create(nil);
FprbAccount.Position := 0;
FstbAccount.Panels[1].text :='Retrieving ' + inttostr(iMsgNo) + ' of total ' + inttostr(iMsgsMaxCount);
try
FPOP.RetrieveMessage(iMsgNo,FMSG);
// 如果去掉此句,则一切OK.不过收不了Mail又有什么用.
except
FstbAccount.Panels[0].text :='Abort,Disconnect';
FstbAccount.Panels[1].text :='Retrieve The ' + inttostr(iMsgNo) + ' Mail Fail';
FMSG.Free;
FPOP.Quit;
exit;
end;
//..保存并打印
//..
FMSG.AttachedFiles.Clear;

FMSG.Free;
end;
end
else
FstbAccount.Panels[1].text :='No Mail Found';
FPOP.quit;
FstbAccount.Panels[0].text :='Disconnect';
FstbAccount.Panels[1].text :='';
end;
 
提问者:
如果你还要继续讨论请定期提前你的帖子,如果不想继续讨论请结束帖子。
请认真阅读大富翁论坛规则说明 http://www.delphibbs.com/delphibbs/rules.asp
 
粗略地看了一下你的代码
我做过在线程中封装sakemail的程序
据我的经验,这种错误最大的可能是不应该在线程中直接访问可视控件
比如:
procedure TClsSakPOP.SakPOPAfterRetrieve(Sender: TObject);
begin
FstbAccount.Panels[0].text := 'This Mail Retrieved ..';
FprbAccount.Visible:=False;
end;
这种方式是不合适的
我的办法是向主线程发送一个自定义的message,由主线程访问可视控件
 
不应该在线程中直接访问可视控件
要访问可视控件,应调用线程的synchronize来访问。
 
用synchronize实现的话,就可能不是同时了。
 

你的线程释放时,
TClsSakPOP.free;
TClsSakPOP.waitfor;
//连续多个线程释放时,用一下这个函数
。。。。。
TClsSakPOP.free;
TClsSakPOP.waitfor;
//连续多个线程释放时,用一下这个函数
 
多人接受答案了。
 
后退
顶部