Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизРабота с потоком и как подружится с FTP Найти похожие ветки
← →
Xmen (2012-06-26 15:28) [0]Несколько год назад сделал для филиала прогу для подготовке к отправке файла. У нас все файле архива (arj) для отправке имеют вид 8.3 формат внутри тоже. Архив (ммммАВа.ааа - мммм код принимающего филиала, -А код дня, -В номер рейса, -аааа код отправляющего филиала. А внутри архива ххааааАВ.еее -хх код отдела головного управления (напр. компьютерный kp) , еее расширение файла. Раньше было просто моя прога подготавливал файл и отправлял в папку для отправки. Между филиалом и головным управлением был защищенный канал и там работала прога CM-клиент. Теперь у нас своя сетка CM-клиент отменили слишком много ресурсов использовал. В сервере установил FTP сервер FileZilla открыл папки филиалам для отправки и приёму. В сервер установил прогу для сортировки файлов. Теперь немножко о проблеме. В одной проге сделал форму для подготовке к отправке файла и форму для отправке файла в FTP сервер. На форме установлен таймер в определенное время обновляется папка для подготовки к отправки файла и для отправки и приёма из FTP, если FTP папки не пустые то заработает процедура для отправки или приёма по FTP. Проблема в том если идет скачка или отправка из FTP то не могу переходить в форму для подготовке к отправки. (Формы в одном пейджконтроле). Отправку и приём по FTP поместил поток но все равно не получается переход. Потоками и FTP начел работать только в этом проекте. Как можно организовать работу потока и работу с FTP(докачка).
← →
Cobalt © (2012-06-26 15:57) [1]главное - проверяй, не запущен ли у тебя уже поток, а команды типа "отправить файлы" ил "принять файлы" помещай в объект (список. или в переменную какую), защищенную критической секцией.
Ключевые слова - Read Many, Write One.
← →
Xmen (2012-06-26 16:04) [2]и еще я работаю из потока с компонентом ProgressBar это допустимо?
← →
ProgRAMmer Dimonych © (2012-06-26 16:09) [3]> [2] Xmen (26.06.12 16:04)
> и еще я работаю из потока с компонентом ProgressBar это
> допустимо?
Зря.
← →
Германн © (2012-06-26 16:41) [4]
> Отправку и приём по FTP поместил поток
И засунул в Synchronize небось?
← →
Xmen (2012-06-26 16:44) [5]
> И засунул в Synchronize небось?
нет
> Зря.
вот и спрашиваю
← →
Anatoly Podgoretsky © (2012-06-26 16:55) [6]> Xmen (26.06.2012 16:44:05) [5]
Не врешь?
← →
sniknik © (2012-06-26 16:58) [7]> Не врешь?
Зря.
;))))
← →
antonn © (2012-06-26 22:25) [8]
> Xmen (26.06.12 16:04) [2]
>
> и еще я работаю из потока с компонентом ProgressBar это
> допустимо?
допустимо если потоки синхронизируются
← →
Германн © (2012-06-27 02:34) [9]
> Xmen (26.06.12 16:44) [5]
>
> > И засунул в Synchronize небось?
>
> нет
>
Не верю! Приведи код реализации того потока, в котором ты осуществляешь "Отправку и приём по FTP".
← →
Xmen (2012-06-27 08:34) [10]
> Не врешь?
> Не верю! Приведи код реализации того потока, в котором ты
> осуществляешь "Отправку и приём по FTP".
Извиняюсь нашелся Synchronize просто не заметил :(
Вот кусок кода в потоке
procedure MyThread.Refresh;
begin
if not Form1.lbFile.Items.Count=null then
begin
Form1.RefreshFile;
Form1.RefreshSending;
end;
if Form1.lbFileSend.Items.Count=0 then
begin
Form1.RefreshFile;
Form1.RefreshSending;
end;
Form1.refreshFTPsend;
Form1.refreshDir;
if Form1.ListView3.Items.Count>0 then
begin
Form1.Timer1.Enabled:=False;
Form1.Button7.Click;
Form1.Timer1.Enabled:=True;
end;
if Form1.ListView2.Items.Count>0 then
begin
Form1.Timer1.Enabled:=False;
Form1.Button8.Click;
Form1.Timer1.Enabled:=True;
end;
end;
procedure MyThread.Execute;
begin
{ Place thread code here }
FreeOnTerminate:=true;
Synchronize(Refresh);
if terminated then exit;
end;
Может быть я не правильно использовал поток?
← →
Anatoly Podgoretsky © (2012-06-27 08:48) [11]> Xmen (27.06.2012 08:34:10) [10]
Вот он Архангельский код, поток по сути не используется
← →
Wadimka (2012-06-27 08:53) [12]Карочь объясняю, по крайней мере я делаю таки все чудесто работает хоть со 100 потоками.
Допустим нужно в одном потоке работать с инетом
Для этого я создаю 2 класса TTHread
1 TTHread запускается при старте проги вообще без синхронизе и всякой ерунды, создаю у него property какие мне нужны, допустим property send:boolean, задача этого tthread вести контроль над другими потоками(потоком) который уже занимается непосредственно отправкой (запускаешь их уже по командам от потока управляющего и тоже без синхронизе)
Если нужно делать отображение на форму, я делаю без синхронизе так (если только 1 поток будет заведомо работать на отправку)
создаю во втором потоке свои property куда и вписываю все необходимые данные, такие как сколько байт принято передано, каков размер нужно передать, также туда вписую сколько он секунд в работе ну и кучу всякой хрени для своих нужд.
при этом твоей проги достаточно по таймеру читать нужные property не боясь перекрестного обращения
Плюс еще поток №1 следит за таймаутом и т.п., если ошибка все терминатит поток и запускает его заново
Если тебе нужно делать одновременно и прием-передачу, делаешь так же поток №1 и массив потоков на прием - отправку, поток №1 будет ими управлять
а твоя прога будет всегда работать, даже если повиснут оба потока и ты их сможешь отрубить.
Ну это так вкраце написал, вроде запутано, но когда делаешь там все просто.
← →
Xmen (2012-06-27 08:59) [13]
> Anatoly Podgoretsky © (27.06.12 08:48) [11]
>
> > Xmen (27.06.2012 08:34:10) [10]
>
> Вот он Архангельский код, поток по сути не используется
может быть я пример в инете нашел
← →
Xmen (2012-06-27 09:01) [14]
> Wadimka (27.06.12 08:53) [12]
>
> Карочь объясняю, по крайней мере я делаю таки все чудесто
> работает хоть со 100 потоками.
> Допустим нужно в одном потоке работать с инетом
> Для этого я создаю 2 класса TTHread
> 1 TTHread запускается при старте проги вообще без синхронизе
> и всякой ерунды, создаю у него property какие мне нужны,
> допустим property send:boolean, задача этого tthread вести
> контроль над другими потоками(потоком) который уже занимается
> непосредственно отправкой (запускаешь их уже по командам
> от потока управляющего и тоже без синхронизе)
>
> Если нужно делать отображение на форму, я делаю без синхронизе
> так (если только 1 поток будет заведомо работать на отправку)
> создаю во втором потоке свои property куда и вписываю все
> необходимые данные, такие как сколько байт принято передано,
> каков размер нужно передать, также туда вписую сколько
> он секунд в работе ну и кучу всякой хрени для своих нужд.
>
>
> при этом твоей проги достаточно по таймеру читать нужные
> property не боясь перекрестного обращения
> Плюс еще поток №1 следит за таймаутом и т.п., если ошибка
> все терминатит поток и запускает его заново
>
> Если тебе нужно делать одновременно и прием-передачу, делаешь
> так же поток №1 и массив потоков на прием - отправку, поток
> №1 будет ими управлять
> а твоя прога будет всегда работать, даже если повиснут оба
> потока и ты их сможешь отрубить.
> Ну это так вкраце написал, вроде запутано, но когда делаешь
> там все просто.
А кусочек кода можно посмотрет
← →
Рамиль © (2012-06-27 09:04) [15]
> Xmen (27.06.12 08:34) [10]
Тут даже не подправишь, надо переписывать. В Synchronize оставить только обращение к VCL.
← →
Сергей М. © (2012-06-27 10:06) [16]
> Wadimka (27.06.12 08:53) [12]
> достаточно по таймеру читать нужные property не боясь перекрестного
> обращения
Ну конечно, чего там бояться, особенно если свойство явно не атомарного типа - string, например)
Нам ведь море по колено)
← →
Wadimka (2012-06-27 10:11) [17]Попробую набросать на пальцах, из каких прог вытащить, сейчас смотрю так каждый поток с кучей своих функций и процедур, слишком много,только запутаю
Вот создаешь допустим unit
в нем создаешь класс TTHread
type
TThread_STARTGetPriceAll = class(TThread)
private
pRunZapros:byte; //===Если 0 - в ожидании, другая цифра, что делать потоку
pWorkTimeOut:integer; //===timeout
pStatusWait:integer; //=====Код статуса
pStoped:boolean; //======Признак завершения потока
protected
procedure Execute; override;
procedure ////====сюда любые процедуры и функции для этого потока
public
property RunZapros:byte read pRunZapros write pRunZapros;
property WorkTimeOut:integer read pWorkTimeOut write pWorkTimeOut;
property StatusWait:integer read pStatusWait write pStatusWait;
property Stoped:boolean read pStoped write pStoped;
end;
...................
procedure TThread_STARTGetPriceAll.Execute;
var
//===Объявляешь если что-то нужно
begin
pRunZapros:=0;
pStoped:=false;
pWorkTimeOut:=0;
pStatusWait:=0;
repeat
Sleep(100);
case pRunZapros of
0:begin
//========Допустим тут инициация всей необходимой среды, сброс счетчиков и т.п.
и т.д.
pRunZapros - ставишь допустим код 1 (при этом ты через таймер с основной формы, легко сможешь обратиться допустим Thread_STARTGetPriceAll.RunZapros и узнать что делает поток по его коду)
Допустим тут
pRunZapros:=1;
На этом команда 0 сработала, и дальше ничего не делает, пока опять repeat until не возобновить работу, соответсвенно следующая команда будет под №1
end;
1:begin
//===Здесь у нас запуск
второго такого потока, который уже будет работать по ftp
THRead:=THRead.Create(true);
и т.п. и т.д.
// И ставим код следующей команды для основного потока
pRunZapros:=2;
end;
2:begin
//==========Поток для работы по ftp запущен и наш управляющий поток об этом знает, тут можно следить за его работой, таймаут например, ожидания признака завершения, коды ошибок и т.п. (описывается в type этот поток по аналогии с этим потоком, только с набором своих функций, процедур переменных) Доступ к которым через property можно делать без синхронизации
pWorkTimeOut:=pWorkTimeOut+1;
делаем првоерку, скажем на завершение работы второго потока
if THRead.OkWork=true then //значит он закончил свою работу переходим к обработке результата его работы при этом его не нужно дестроить, принимать решение будешь дальше и ставим команду дальше,
pRunZapros:=3;
end;
3:begin
тут обрабатываем то, что вернул поток рабоnf.onq по ftp
если ошибка то идем на команду pRunZapros:=1;
если гут, то дестроим тот поток, предварительно забрав всю инфу после его работы.
При этом как ты понял, обращаясь из основной формы к property этого (управляющего потока), допустим form1 по таймеру, ты будешь видеть что он делает, как отработал 2-q поток по ftp и т.п.
end;
end;
until pStoped;
//====Если ты из основной формы установишь переменную
Thread_STARTGetPriceAll.Stoped в true то основной поток прекратит работу
end;
В своей форме, в var объявлешь подключив этот unit
var
Thread_STARTGetPriceAll:TThread_STARTGetPriceAll;
при этом организация через case лично мне нравиться тем, что по результатам работы потоков можно самому управлять ходом на какую стадию вернуться.
Вообщем я так побырому набросал, если есть вопросы оставляй аську помогу.
Так же можно усложнить, если этот поток будет управлять массивом потоков, делаешь также
var
DPotok:array of TMyTHread;
и работаешь с ними, контроллируя работу всех потоков
У меня были проги, где я таким способом управлял около 20-ти потоков, которые выполняли каждый свою работу, допустим, чтобы получить результат конечный для потока 5, нужно чтоб поток 1 2 и 3 отработали правильно, если 1 и 3 сработали нормально, а второй ушел в тайм-аут, управляющий поток не будет перезапускать 2-й поток, пока не получит от него данные не трогая 1 и 3 потоки, как получил запустил 5-й
Я так по скорому набросал, а пример кода я даже не пойму как накатать, все зависит уже от твоих потребностей.
Если что пиши помогу
← →
Wadimka (2012-06-27 10:13) [18]
> > Wadimka (27.06.12 08:53) [12]
>
>
> > достаточно по таймеру читать нужные property не боясь
> перекрестного
> > обращения
>
>
> Ну конечно, чего там бояться, особенно если свойство явно
> не атомарного типа - string, например)
>
> Нам ведь море по колено)
Предполагается, что все property будут четко ограниченного типа и структуры
← →
Wadimka (2012-06-27 10:17) [19]а это 2, по таймеру читать то, что нужно для определения статуса, сколько принято-отправлено кбайт, тайм-аут, время работы
и какие проблемы читать все из основной формы по таймеру?
не нравится так, делаешь функция, ViewToForm
за запускаешь ее через синхронизе из управляющего потока и какие проблемы не пойму
← →
Сергей М. © (2012-06-27 11:02) [20]
> Wadimka
Дурные советы ты даешь.
> какие проблемы читать все из основной формы по таймеру?
Встречный вопрос - какие проблемы послать форме из доп.потока асинхронные сообщения ?
Как только осн.поток будет свободен, он получит то что ему адресовано.
Незачем его мочалить таймером, особенно в случае когда инф-ция о доп.потоке, требуемая к отображению в GUI, изменяется во времени сравнительно нечасто.
← →
Wadimka (2012-06-27 11:39) [21]> Сергей М.
Это все называется просто: одно из решений
← →
Anatoly Podgoretsky © (2012-06-27 11:52) [22]> Сергей М. (27.06.2012 11:02:20) [20]
> асинхронные сообщения
Зачем тогда доп.поток
С асинхронными сообщениями реально тысяч 30 одновременных закачек в одном
потоку, в основном
← →
Сергей М. © (2012-06-27 12:32) [23]
> Anatoly Podgoretsky © (27.06.12 11:52) [22]
> Зачем тогда доп.поток
Затем чтобы разместить в нем имеющийся синхронный ftp-транспорт, отказаться от которого в пользу асинхронного по каким-либо важным причинам не представляется возможным.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.066 c