Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.061 c
6-1262631738
Антон80
2010-01-04 22:02
2013.03.22
Проблема с темой письма в TIdSMTP


15-1336681802
Юрий
2012-05-11 00:30
2013.03.22
С днем рождения ! 11 мая 2012 пятница


6-1260958453
zsv
2009-12-16 13:14
2013.03.22
Непонятно поведение TIdTCPServer


15-1344870494
stas
2012-08-13 19:08
2013.03.22
DelphiXE 2 FireMonkey


15-1331894772
Palladin
2012-03-16 14:46
2013.03.22
msscript control





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский