Текущий архив: 2003.01.27;
Скачать: CL | DM;
Вниз
Кто-нибудь в тредах отправлял почту или файлы по ftp ? Найти похожие ветки
← →
Vovaka (2003-01-17 10:11) [0]Идея в том, чтобы отправлять некую статистику по почте либо по ftp в тредах, чтобы основной процесс не ждал окончания отсылки. Но сталкнулся с проблемой, что когда это дело запихнул в тред, то перестал работать NMSMTP1.Connect (NMFTP1.Connect). Просто виснет на этой строчке. В чем может быть дело ?
← →
Digitman (2003-01-17 10:23) [1]
> Просто виснет на этой строчке
А как ты это определил ? В пошаговой трассировке ? Или как ?
Ты осознаешь, что Connect-методы этих компонентов могут работать в блок.режиме и их выполнение может привести к исключению (например, по недоступности хоста) ? Ты осознаешь, что трэд-функция ОБЯЗАНА обрабатывать любые исключения, возникшие в ходе ее выполнения, таким образом, чтобы они были "погашены" ДО ее завершения ? У тебя в трэд-функции есть внешний блок перехвата/обработки исключений try..except ?
← →
Vovaka (2003-01-17 10:33) [2]Естественно все это выполняется в try..except, но исключение не вызывается, в отладчике видно, что в конце концов выполнение кода(NMXXX.Connect) попадает в бесконечный цикл ...
← →
Smithson (2003-01-17 10:39) [3]Это как? В исходниках NMFTP? Или просто после коннекта управление пропадает?
← →
Vovaka (2003-01-17 10:43) [4]В исходниках
← →
Anatoly Podgoretsky (2003-01-17 11:00) [5]Возьми более сложные компоненты, FastNet очень тяжел для понимания начинающими
← →
Digitman (2003-01-17 11:14) [6]
> Vovaka
У меня, к сож, Д5, а не Д6
И исходники FastNet, как помнится, в Д5 отсутствуют, только DCU.
Но если ты говоришь, что трассировал код Connect в Д6, значит, исходники есть у тебя ? Тогда приведи текст "бесконечного" цикла. Я не думаю, что при наличии исходников так уж сложно локализовать проблему
← →
Vovaka (2003-01-17 11:18) [7]Я имею ввиду ассемблерный код
← →
Digitman (2003-01-17 11:29) [8]
> Vovaka
Ну а какие-либо события-то этих компонентов обрабатываешь ? И - как ? Приводи код трэда
← →
Vovaka (2003-01-17 11:44) [9]События не обрабатываю
destructor TSender.Destroy;
begin
Dec(ThreadSendCount);
case Mode of
0: begin
if NMFTP1 <> nil then
NMFTP1.Free;
NMFTP1 := nil;
end;
1: begin
if NMSMTP1 <> nil then
NMSMTP1.Free;
NMSMTP1 := nil;
end;
end;
Inherited Destroy;
end;
constructor TSender.Create(_Mode : Byte; _Host, _UserID, _FTPPassword, _FromName, _FromAddress, _EMailAddress, _Body, _Subj, _Dir,
_FileName, _MsgOk, _MsgFail : String);
// Mode 0: FTP; 1: EMail
begin
Inherited Create(false);
FreeOnTerminate := true;
Priority := tpNormal;
Mode := _Mode;
Host := _Host;
UserID := _UserID;
FTPPassword := _FTPPassword;
FromName := _FromName;
FromAddress := _FromAddress;
EMailAddress := _EMailAddress;
Body := _Body;
Subj := _Subj;
Dir := _Dir;
FileName := _FileName;
MsgOk := _MsgOk;
MsgFail := _MsgFail;
Inc(ThreadSendCount);
case Mode of
0: NMFTP1 := TNMFTP.Create(nil);
1: begin
NMSMTP1 := TNMSMTP.Create(nil);
NMSMTP1.Charset := "windows-1251";
end;
end;
end;
procedure TSender.AddToLog;
begin
Main.AddToLog(Status, StatusMsg)
end;
function TSender.TrimBlanks(s : String) : String;
begin
while Pos(" ", s) <> 0 do
Delete(s, Pos(" ", s), 1);
while Pos(";", s) <> 0 do
s[Pos(";", s)] := ",";
Result := s;
end; { TrimBlanks }
procedure TSender.SendByFTP;
var
i : Word;
begin
Status := false;
NMForm.NMFTP1.Host := Host;
NMForm.NMSMTP1.Charset := "windows-1251";
NMForm.NMFTP1.UserID := UserID;
NMForm.NMFTP1.Password := FTPPassword;
for i := 1 to 1000 do
try
if not NMForm.NMFTP1.Connected then
NMForm.NMFTP1.Connect;
NMForm.NMFTP1.Mode(MODE_ASCII);
NMForm.NMFTP1.Upload(Dir + "\" + FileName, FileName);
Status := true;
Break;
except
on E : Exception do
try
Sleep(5000);
StatusMsg := E.Message;
NMForm.NMFTP1.DisConnect;
except
end;
end;
NMForm.NMFTP1.DisConnect;
if FileName <> "" then
try
DeleteFile(Dir + "\" + FileName);
except
end;
if Status then
StatusMsg := MsgOk
else
StatusMsg := MsgFail + " " + StatusMsg;
if StatusMsg <> "" then
Synchronize(AddToLog);
end; { SendByFTP }
procedure TSender.SendByEMail;
var
i : Word;
begin
Status := false;
NMForm.NMSMTP1.Host := Host;
NMForm.NMSMTP1.UserID := UserID;
NMForm.NMSMTP1.PostMessage.FromAddress := FromAddress;
NMForm.NMSMTP1.PostMessage.FromName := FromName;
EMailAddress := TrimBlanks(EMailAddress);
NMForm.NMSMTP1.PostMessage.ToAddress.Clear;
while Pos(",", EMailAddress) <> 0 do
begin
NMForm.NMSMTP1.PostMessage.ToAddress.Add(Copy(EMailAddress, 1, Pos(",", EMailAddress)-1));
Delete(EMailAddress, 1, Pos(",", EMailAddress));
end;
NMForm.NMSMTP1.PostMessage.ToAddress.Add(EMailAddress);
NMForm.NMSMTP1.PostMessage.Body.Clear;
NMForm.NMSMTP1.PostMessage.Body.Add(BillingSystem);
NMForm.NMSMTP1.PostMessage.Body.Add("");
NMForm.NMSMTP1.PostMessage.Body.Add(Body);
NMForm.NMSMTP1.PostMessage.Body.Add("");
NMForm.NMSMTP1.PostMessage.Body.Add(FormatDateTime("yyyy.mm.dd hh:nn:ss", Now));
NMForm.NMSMTP1.PostMessage.Subject := Subj;
NMForm.NMSMTP1.PostMessage.LocalProgram := BillingSystem;
if FileName <> "" then
NMForm.NMSMTP1.PostMessage.Attachments.Text := Dir + "\" + FileName;
for i := 1 to 1000 do
try
if not NMForm.NMSMTP1.Connected then
NMForm.NMSMTP1.Connect;
NMForm.NMSMTP1.SendMail;
Status := true;
Break;
except
on E : Exception do
try
Sleep(1000);
StatusMsg := E.Message;
NMForm.NMSMTP1.DisConnect;
except
end;
end;
NMForm.NMSMTP1.DisConnect;
if FileName <> "" then
try
DeleteFile(Dir + "\" + FileName);
except
end;
if Status then
StatusMsg := MsgOk
else
StatusMsg := MsgFail + " " + StatusMsg;
if StatusMsg <> "" then
Synchronize(AddToLog);
end; { SendByEMail }
procedure TSender.Execute;
begin
case Mode of
0: SendByFTP;
1: SendByEMail;
end;
end;
← →
Smithson (2003-01-17 11:50) [10]Не стоит использовать в потоке объект, лежащий на основной форме.
Создавай его в начале Execute и грохай в его конце. И не ставь владельцем форму - или nil (не помню, можно так с NMFTP) или Application.
← →
Vovaka (2003-01-17 12:03) [11]Я пробовал и без объекта с основной формы, и владельца ставил и nil и Application и еще что-то - не помогает
← →
Digitman (2003-01-17 12:06) [12]Очень, очень много грубых ошибок и некорректностей !!!!
Переделывать придется практически каждый метод класса TSender.
Начнем с конструктора.
begin
Inherited Create( false);
...
end;
почему FASLE ? нет этому разумного объяснения.
доп.поток немедленно стартует при этом, а ты все еще телишься с записью переданных параметров в поля объекта. А доп.поток УЖЕ обращается к этим полям !!!
Далее.
procedure TSender.Execute;
begin
//где try ???
case Mode of
0: SendByFTP;
1: SendByEMail;
end;
//где except..end ???
end
исправляй пока это, потом будет еще куча серьезных замечаний
← →
Digitman (2003-01-17 12:24) [13]общая примерная схема д.б. такова :
TSender = class(TThread)
private
// поля для сохранения и использования в трэде передаваемых параметров
FSomeFastNetComponent: TSomeFastNetComponent;
FExcName : string;
FExcMsg : string;
procedere LogExceptions;
protected
procedure Execute; override;
public
consctuctor Create(передаваемые параметры)
end;
consctuctor TSender.Create(передаваемые параметры);
begin
inherited Create(True);
// сохраняем параметры
Resume;
end;
procedure TSender.Execute;
begin
try
FSomeFastNetComponent := TSomeFastNetComponent.Create(nil);
try
// работаем с FSomeFastNetComponent с учетом параметров, переданных трэду
finally
FSomeFastNetComponent.Free;
end;
except
on e:exception do
begin
FExcName := e.ClassName;
FExcMsg := e.message;
try
Synchronize(LogExceptions);
except
end;
end;
end;
end;
procedere TSender.LogExceptions;
begin
// обращаемся к файлу, форме и т.д. (т.е. неразделяемым ресурсам) с целью записи лога
end;
← →
Vovaka (2003-01-17 12:51) [14]С учетом замечаний (за них отдельное спасибо) все равно результат
тот же.
← →
Digitman (2003-01-17 12:52) [15]ну так приведи код с учетом замечаний !
← →
Vovaka (2003-01-17 13:09) [16]constructor TSender.Create(_Mode : Byte; _Host, _UserID, _FTPPassword, _FromName, _FromAddress, _EMailAddress, _Body, _Subj, _Dir,
_FileName, _MsgOk, _MsgFail : String);
// Mode 0: FTP; 1: EMail
begin
Inherited Create(true);
FreeOnTerminate := true;
Priority := tpNormal;
Mode := _Mode;
Host := _Host;
UserID := _UserID;
FTPPassword := _FTPPassword;
FromName := _FromName;
FromAddress := _FromAddress;
EMailAddress := _EMailAddress;
Body := _Body;
Subj := _Subj;
Dir := _Dir;
FileName := _FileName;
MsgOk := _MsgOk;
MsgFail := _MsgFail;
Inc(ThreadSendCount);
case Mode of
0: NMFTP1 := TNMFTP.Create(nil);
1: begin
NMSMTP1 := TNMSMTP.Create(nil);
NMSMTP1.Charset := "windows-1251";
end;
end;
Resume;
end;
procedure TSender.SendByEMail;
var
i : Word;
begin
Status := false;
NMSMTP1.Host := Host;
NMSMTP1.UserID := UserID;
NMSMTP1.PostMessage.FromAddress := FromAddress;
NMSMTP1.PostMessage.FromName := FromName;
NMSMTP1.PostMessage.ToAddress.Clear;
NMSMTP1.PostMessage.ToAddress.Add(EMailAddress);
NMSMTP1.PostMessage.Body.Clear;
NMSMTP1.PostMessage.Body.Add(Body);
NMSMTP1.PostMessage.Subject := Subj;
for i := 1 to 1000 do
try
if not NMSMTP1.Connected then
NMSMTP1.Connect;
NMSMTP1.SendMail;
Status := true;
Break;
except
on E : Exception do
try
Sleep(1000);
StatusMsg := E.Message;
NMSMTP1.DisConnect;
except
end;
end;
NMSMTP1.DisConnect;
if FileName <> "" then
try
DeleteFile(Dir + "\" + FileName);
except
end;
if Status then
StatusMsg := MsgOk
else
StatusMsg := MsgFail + " " + StatusMsg;
if StatusMsg <> "" then
Synchronize(AddToLog);
end; { SendByEMail }
procedure TSender.Execute;
begin
try
case Mode of
0: SendByFTP;
1: SendByEMail;
end;
except
Status := false;
Synchronize(AddToLog);
StatusMsg := "Ошибка выполнения треда.";
end;
end;
← →
Vovaka (2003-01-17 13:13) [17]Да и если вместо NMSMTP использовать IdSMTP, то Connect проходит, но на Send вызывается исключение, которое посылает по адресу http://pobox.com/~djb/docs/smtplf.html
← →
Vovaka (2003-01-17 13:19) [18]Sorry за предыдущий пост, вот Indy как раз и заработал после ваших замечаний, а вот NM не хотят...
← →
Digitman (2003-01-17 13:21) [19]все равно - каша какая-то) ... крайне запутанная логика !
ну да ладно) .. и что ? хочешь сказать, что брейкпойнт на строчке Status := false не "ловится" ни при каких условиях ? ни сразу ни по истечении таймаута (1..3 мин) ?
← →
Vovaka (2003-01-17 13:37) [20]Не-а, ну может бог с ним, буду Indy использовать, тем более, если на семерку переходить, там FastNet по умолчанию даже и не ставится. В общем большое вам спасибо.
← →
Digitman (2003-01-17 13:45) [21]
> Vovaka
Indy, конечно, не панацея (при весьма сомнительном твоем понимании сути происходящего в треде), но там хоть исходники есть
Страницы: 1 вся ветка
Текущий архив: 2003.01.27;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.008 c