Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как остановить закачку в IdHttp? [D7, WinXP]


Страницы:   1 2

vegarulez ©   (2010-10-12 10:30:00) 

Привет всем мастерам!
Вопрос состоит в следующем в основном потоке создаётся дополнительный - который скачивает с сервера нужный мне файл, и докачивает его, потом если вдруг соединение к интернету было разорвано. Вопрос заключается в следующем - как принудительно отключить скачивание, по нажатию на кнопоку.
Т.к. там происходит взаиможействи на уровне idhttp в процедуре idHTTP1Work
пытаюсь сделать terminate потока  - но закачка всёравно продолжается. подскажите.


...
const
MY_MESS = WM_USER + 1;
type
 TFormMain = class(TForm)
   ProgressBar1: TProgressBar;
   Edit1: TEdit;
   Edit2: TEdit;
   Button3: TButton;
   Button8: TButton;
...

 type
 TDownLoadfile = class(TThread)
 private
   FSourceFile, FSourceURL: string;
   FSizeFile: Dword;
   IdHTTP1:TidHttp;
   protected
     procedure Execute;override;
   public
     property SourceURL:string read FSourceURL write FSourceURL;
     property SourceFile:string read FSourceFile write FSourceFile;
     property SizeFile:Dword read FSizeFile write FSizeFile;
     procedure idHTTP1Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
     procedure idHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
    procedure idHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
 end;

...

procedure TFormMain.Button3Click(Sender: TObject);
begin
 SaveDialog1.FileName:=copy(Edit1.Text,LastDelimiter('\/',Edit1.Text)+1,maxint);
 if SaveDialog1.Execute then
    Edit2.Text:=SaveDialog1.FileName;
end;

procedure TFormMain.MyProgress(var msg: TMessage);
begin
 case msg.WParam of
 0:
  begin
   {label4.Caption:= formatfloat('0.00',msg.LParam / 1024 / 1024) +' мб ('+inttostr(msg.LParam)+')';
   L_P_Num_1.Caption:= formatfloat('0.00',(RestartPos+msg.LParam)  / 1024 / 1024) +' мб ('+inttostr(RestartPos+msg.LParam) +')';}

   ProgressBar1.Max:=RestartPos+msg.LParam;
   ProgressBar1.Position:=0;
  end;
 1:
  begin
   {label5.Caption:=formatfloat('0.00',msg.LParam / 1024 / 1024)+' мб ('+inttostr(msg.LParam)+')';
   label10.Caption:= formatfloat('0.00',(RestartPos+msg.LParam) / 1024 / 1024) +' мб ('+inttostr(RestartPos+msg.LParam)+')'+' [ '+formatfloat('0',((RestartPos+msg.LParam)/ProgressBar1.Max*100)) +'% ]';}

   ProgressBar1.Position:=RestartPos+msg.LParam;
  end;
 end;
end;

procedure TFormMain.thrTerminate(Sender: TObject);
begin
 ShowMessage('Готово');
 Button8.Enabled:=true;
end;

procedure TDownLoadfile.idHTTP1Work(ASender: TObject; AWorkMode: TWorkMode;
 AWorkCount: Integer);
begin
 PostMessage(Application.MainForm.Handle,MY_MESS,1,AWorkCount);
end;

procedure TDownLoadfile.idHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
 AWorkCountMax: Integer);
begin
 PostMessage(Application.MainForm.Handle,MY_MESS,0,AWorkCountMax);
end;

procedure TDownLoadfile.idHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
//
end;

procedure TFormMain.BT_Stop_downloadClick(Sender: TObject);
var
t:TDownLoadfile;
begin
t.IdHTTP1.EndWork;

end;

{ TDownLoadfile }

procedure TDownLoadfile.Execute;
var

FileDate: TDateTime;
FileType: string;
SourceFileSize: Dword; // размер исходного файла который собираемся скачивать
fDownloadStream: TFileStream;
begin
IdHTTP1:=TIdHTTP.Create(nil);
IdHTTP1.OnWork:=IdHTTP1Work;
IdHTTP1.OnWorkBegin:=IdHTTP1WorkBegin;
IdHTTP1.OnWorkEnd:=IdHTTP1WorkEnd;
IdHTTP1.ProtocolVersion := pv1_1; //pv1_1
IdHTTP1.HandleRedirects := True;
IdHTTP1.Head(SourceURL);
SourceFile :=IdHTTP1.Response.RawHeaders.Text; // Values['ETag'], '"', '', [rfReplaceAll]), '-', '', [rfReplaceAll]);  //
SourceFile := StringReplace(StringReplace(IdHTTP1.Response.RawHeaders.Values['ETag'], '"', '', [rfReplaceAll]), '-', '', [rfReplaceAll]);  //   Text;
SourceFile := IdHTTP1.URL.Document;
SourceFileSize := IdHTTP1.Response.ContentLength;

if SourceFileSize>SizeFile then           // значит файл не докачан или его нет вовсе.
Begin
FileDate := IdHTTP1.Response.LastModified;
FileType := IdHTTP1.Response.ContentType;

if FileExists(IdHTTP1.URL.Document) then
 begin
  fDownloadStream := TFileStream.Create(SourceFile, fmOpenReadWrite);
  fDownloadStream.Position:=SizeFile;
  Idhttp1.Request.Range:=Format('%d-%d',[fDownloadStream.Position,SourceFileSize]);
  fDownloadStream.Seek(fDownloadStream.Position,soFromBeginning);
 end
else
 begin
  fDownloadStream := TFileStream.Create(SourceFile, fmCreate);
  fDownloadStream.Seek(0,soFromBeginning); //
 end;
IdHTTP1.Request.ContentType := FileType;
IdHTTP1.Request.ContentRangeStart := fDownloadStream.Position;
IdHTTP1.Request.ContentRangeEnd := SourceFileSize;
try
 IdHTTP1.Get(SourceURL,fDownloadStream);
finally
 fDownloadStream.Free;
 IdHTTP1.Free;
end;
End
else
terminate;
end;

function GetFileSize(FileName: String): Integer;
var
 FS: TFileStream;
begin
 try
   FS := TFileStream.Create(Filename, fmOpenRead);
 except
   Result := -1;
 end;
 if Result <> -1 then Result := FS.Size;
 FS.Free;
end;

procedure TFormMain.Button8Click(Sender: TObject);
var
t:TDownLoadfile;
begin

 Button8.Enabled:=false;

 //Создадим класс потока.
 //Поток для начала будет остановлен
 t:=TDownLoadfile.Create(true);
 //Передадим параметры потоку
 t.SourceURL:=Edit1.Text;
 t.SourceFile:=Edit2.Text;
 RestartPos:=0;
 //Если на винте есть файл то считаем, что нужно докачивать
 if FileExists(Edit2.Text) then
  RestartPos:=GetFileSize(Edit2.Text);    //*128
 t.SizeFile:=RestartPos;

 //Поток должен удалить себя по завершению своей работы
 t.FreeOnTerminate:=true;
 t.OnTerminate:=thrTerminate;

 //И запустим его на закачку.
 t.Resume;
 //Теперь с процедуры мы выйдем, но поток работает
 //и живёт своей жизней
end;


sniknik   (2010-10-19 09:38:00) [1]

> Почему не работает код выше?
а он действительно не работает? тогда причина однозначна - вызов Get синхронный, пока не выполнится, дрогой код в этом потоке (неважно где описан) выполнятся не будет.

(вариант когда будет, это если описан метод типа onWorkInProccess который периодически вызывается в самом Get)


sniknik   (2010-10-19 09:32:00) [2]

> но сама процедура Work(если она созданна в доп. потоке), должна работать и в нем?
с чего такие инсинуации? код работает там где вызван, а не там где описан.

> Я и спрашиваю -
ты навыдумывал себе "страшилок" и спрашиваешь не по тому что предлагали, а по тому, что у тебя в голове.


HF-Trade   (2010-10-19 08:43:00) [3]

То что Start присвоить false из другого потока понятно(основного к примеру), ибо доп.поток висит на Get, но сама процедура Work(если она созданна в доп. потоке), должна работать и в нем?


HF-Trade   (2010-10-19 08:37:00) [4]

ммм... событие Work можно описать и в доп.потоке.
Я и спрашиваю -
1. Почему из другого потока?
2. Почему не работает код выше? хотя там из VCL закрываем сокет, он тупо висит пока не закончится ConnectionTimeout


sniknik   (2010-10-19 08:10:00) [5]

> Почему из другого потока?
а почему у тебя так же? вот Http.Get у тебя в дополнительном, а Start для остановки ты False  будешь присваивать в каком? судя по всему в другом, основном.
хочешь попытайся в том же, дополнительном, посмотрим как у тебя получится.


HF-Trade   (2010-10-19 07:39:00) [6]

ошибся, Work, конечно, не workend


HF-Trade   (2010-10-19 07:27:00) [7]


> Из другого потока вызови IdHTTP.Socket.Close, тогда IdHTTP.
> Get() возвратит управление с соотв.исключением

Почему из другого потока?
Поясните почему не будет работать -
...
{В потоке}
 AIdHttp := TIdHttp.Create(nil);
 AIdHttp.OnWork := Form1.IdHttp1Work;
Try
 Try
  AIdHttp.Get(URL);
 Except
 end;
Finally  
 AIdHttp.Free;
....
{На форме}
procedure TForm1.IdHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
IF Start = False Then
 (ASender as TIdHttp).Socket.Close;
end;


Anatoly Podgoretsky   (2010-10-17 17:52:00) [8]

> vegarulez  (17.10.2010 17:41:25)  [25]

Да не за что, мы приложили все силы.


vegarulez   (2010-10-17 17:41:00) [9]

Anatoly Podgoretsky ©   (17.10.10 15:13) [20]
sniknik ©   (17.10.10 15:42) [21]

Спасибо большое.


Anatoly Podgoretsky   (2010-10-17 17:28:00) [10]

Все решение перебраны и это тоже.


Palladin   (2010-10-17 16:47:00) [11]

Предлагаю нанять программиста.


Плохиш   (2010-10-17 16:14:00) [12]


> vegarulez   (17.10.10 14:38) [19]

Тебе уже предлагали нанять программиста?


sniknik   (2010-10-17 15:42:00) [13]

имхо, лучше описать сам поток до формы... (какие то проблемы с тем что что форма не первая?), а еще лучше в отдельном модуле и прописать его в юзес раздела интерфасе.


Anatoly Podgoretsky   (2010-10-17 15:13:00) [14]

> vegarulez  (17.10.2010 14:38:19)  [19]

Поставь перед  TDownLoadfile = class;


vegarulez   (2010-10-17 14:38:00) [15]

Сергей М. ©   (13.10.10 16:55) [13]

Я же написал vegarulez   (13.10.10 16:38) [12]
что когда так делаю - выскакивает ошибка при компиляции.
Так как

 type
 TDownLoadfile = class(TThread)
 private
...
 end;


Описан после описния TForm1 = class(TForm)
то он ругается при компиляции на

TForm1 = class(TForm)
..
private
t:TDownLoadfile;
..
end;


т.к. не знает что такое TDownLoadfile


sniknik   (2010-10-15 18:27:00) [16]

> не )
> Основная ("Начинающим" ("Никогда не закончащим"))
детский сад. с лозунгом "нас не научишь..." под песню та-ту.


Сергей М.   (2010-10-13 22:02:00) [17]


> Palladin ©   (13.10.10 21:25) [16]


Я понял про что ты)

Но лучше бы таки "Орешник" реанимировать)


Palladin   (2010-10-13 21:25:00) [18]

не )
Основная ("Начинающим" ("Никогда не закончащим"))


Сергей М.   (2010-10-13 21:24:00) [19]


> Palladin ©   (13.10.10 20:35) [14]


"Патрепацца" ?)


Palladin   (2010-10-13 20:35:00) [20]

по-моему на этом сайте не хватает еще одной конференции


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо