Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Работа с потоком и как подружится с 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.051 c
15-1331287470
Александар
2012-03-09 14:04
2013.03.22
Подмена(дублированя) пакетов между клиентом и определёном ip


15-1330633805
Юрий
2012-03-02 00:30
2013.03.22
С днем рождения ! 2 марта 2012 пятница


15-1335956639
Vik
2012-05-02 15:03
2013.03.22
Delphi7 help


2-1345045236
начинающий7
2012-08-15 19:40
2013.03.22
TreeView


2-1328181215
harisma
2012-02-02 15:13
2013.03.22
Корректно освободить память