Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.01.27;
Скачать: [xml.tar.bz2];

Вниз

Кто-нибудь в тредах отправлял почту или файлы по 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.011 c
1-86849
Анатолий
2003-01-18 21:18
2003.01.27
Консольное приложение


1-86734
pet
2003-01-17 11:55
2003.01.27
Работа с ярлыком


3-86677
Андрю-ХА
2003-01-08 17:36
2003.01.27
Пометка записей пользователем


14-87021
AlexG
2003-01-08 13:22
2003.01.27
Интервал между нажатиями


1-86952
Дмитрий К.К.
2003-01-16 09:52
2003.01.27
Общее свойство компонентов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский