Форум: "Начинающим";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];
ВнизIdFTP & CreateThread Найти похожие ветки
← →
_Андрей (2009-04-14 12:26) [0]Здравствуйте, мне было необходимо организовать обмен с ftp.
Использовал компонент IdFTP, работу с этим компонентом вынес в отдельный поток, только вот загвоздка в том что поток этот не "VCL-й", я просто вызываю WinAPI-функцию CreateThread() ну и так далее.
Пока (тьфу-тьфу-тьфу)) всё работает замечательно, только всё-таки "не даёт спокойно спать" вот эта связка с WinAPI-потоком, ведь в родном дельфовом классе исп-ся сп. функция Synchronized которая гарантирует корректную работу с VCL-ными фичами, может "мой вариант" работать нормально всегда или мне просто пока везёт?
У меня на форме в том числе находиться ProgressBar который обновляется через события TIdFTP.OnWorkEvent(а функция TIdFTP.Get() соот-но вызывается из WinAPI-потока), я больше всего за него боюсь.
Подскажите плиз, чреват ли такой вариант ошибками?
← →
Сергей М. © (2009-04-14 12:45) [1]
> или мне просто пока везёт?
Именно так.
Грабли рано или поздно обязательно выстрелят)
Для начала пользуй BeginThread вместо CreateThread.
По поводу же синхронизации с осн.потоком - при обращениях к ыиз. VCL-контролам она обязательна.
← →
_Андрей (2009-04-14 13:09) [2]Жаль, придётся переделывать на родные дельфовые потоки(((
Спасибо за ответ!
← →
Сергей М. © (2009-04-14 13:22) [3]
> Жаль, придётся переделывать на родные дельфовые потоки
Вовсе не обязательно
← →
_Андрей (2009-04-14 14:02) [4]
> Сергей М. © (14.04.09 13:22) [3]
в смысле? можно прояснить..?
← →
Сергей М. © (2009-04-14 16:26) [5]В смысле - задействовать TThread только лишь ради использования одного-единственного метода Synchronize нет никакого резона.
Синхронизация реализуется элементарно, например, при помощи оконных сообщений (см. Send/PostMessage)
← →
_Андрей (2009-04-17 10:48) [6]Да, я теперь так и сделал, действительно очень удобно и здорово, спасибо (хотя на "родной" для Delphi поток всё равно перевёл).
Но появилась такая вот проблема, при команде (пока проявлялось на TIdFTP.List) вылетает сообщение TIdFTPReplyError "Transfer Complete", например вчера эта штука вылетала при каждом запуске, просидел часа 3 так ничего и накопал по этой теме, сегодня же (с утра) - все запуски бес проблем.
Сначала я грешил на свои "потоковые обёртки", но я пробовал вызывать их и вне потока и результат был тем же, я просто не знаю чего же в дальнейшем ждать, подскажите плиз хотя бы в какую сторону смотреть...
← →
_Андрей (2009-04-17 11:01) [7]Да вот ещё кстати, команда List вызывается в конструкции try except и сообщение которое я привёл я вижу только тогда когда запускаю из Delphi естественно, если же запускать из Win то List всегда грит что по указанной маске нет ни одного файла (на самом деле они там конечно есть)
← →
Anatoly Podgoretsky © (2009-04-17 11:31) [8]А ты точно уверен, а что ни будь повесомее.
← →
_Андрей (2009-04-17 11:56) [9]Точно уверен в чём? Я не то что уверен я вообще не знаю что это за ошибка? То что вылазит такой exception - это факт (возможно только что наз-ся он не TIdFTPReplyError а TIdRFCReplyError).
Я приведу ещё как я сделал эту самую "обёртку":type TFtpWorkTh = class(TIdFTP)
public
function thList(List: TStringList; Mask: string; ATimeOut: integer =
DefTimeOut): boolean;
// th - типа в потоке (thread), детали (Details) мне не нужны
...
end;
// и дальше реализацияfunction TFtpWorkTh.thList(List: TStringList; Mask: string;
ATimeOut: integer): boolean;
begin
Result := false;
...
// здесь создаю поток
// ThreadData - данные для потока
FtpThread := TFtpThread2.Create(true);
FtpThread.FtpWorkTh := Self; //
FtpThread.ThreadData.index := 3;
FtpThread.ThreadData.List := List;
FtpThread.ThreadData.Mask := Trim(Mask);
// заполнив нужные для выполнения потока данные я его запускаю
FtpThread.Resume;
// и дальше жду от него ответа
if Wait(ATimeOut) then Result := true
...
end;
в потоке уже это выполняется так:procedure TFtpThread2.Execute;
begin
{ Place thread code here }
case ThreadData.index of
...
3: // list
try
// не знаю как иначе сделать, обращаюсь вот таким образом
TFtpWorkTh(FtpWorkTh).List(ThreadData.List, ThreadData.Mask, false)
// и в опщем на этом месте и вылазит этот РеплиЭррор
except
//
end;
...
end;
TFtpWorkTh(FtpWorkTh).Flag := true // сообщаю классику об окончании работы
end;
не судите строго, понимаю что это "не фонтан", но работало всё замечательно (до появления указанной "проблемки":((( )
← →
Сергей М. © (2009-04-17 12:06) [10]За каким лешим понадобилась эта "обертка" - совершенноь не понятно ..
Реализуется класс-обертка для создания потока и управления им (хоть свой собственный, хоть наследник TThread - неважно), в конструкторе ему передаются параметры для FTP-запроса. Конструктор их запоминает и запускает поток. В поточной ф-ции создается обычный TIdFTP-объект, настраивается в соответствии с переданными через конструктор параметрами и тут же выполняется собственно запрос. Результаты выполнения запроса сохраняются, после чего TIdFTP-объект разрушается и поточная ф-ция завершает выполнение.
← →
_Андрей (2009-04-17 12:17) [11]Спасибо, учту, в следующий раз (здесь несколько похожих программулек надо сделать) так и сделаю (вообще была похожая идея, но мне показалось неправильным каждый раз создавать IdFTP-объект, вот я и решил создать его один раз, а уж потом на него ссылаться), только это вряд ли имеет отношение к тому exception`у о котором я говорил (я ж даже вне потока пробовал TIdFTP.List() и всё равно было тоже самое)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c