Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.01.2015, 17:11   #1
fudihet
Новичок
Джуниор
 
Регистрация: 31.01.2015
Сообщений: 10
По умолчанию Ошибка в довнлоадере

Доброго времени суток!

Помогите найти ошибку. После старта потока файл начинает загружатся а после чего поток зависает

Код:

....

var
  Form1: TForm1;
  WorkMax, TickCount, BytesCount: Int64;
  link: string;

implementation

{$R *.dfm}

function ExtractUrlFileName(const FileName: string): string;
var
  I: Integer;
begin
  I := FileName.LastDelimiter('/');
  Result := FileName.SubString(I + 1);
end;

function SizeOfFile(Size: Double): String;
begin
  if Size < 1024 then
    Result := Format('%.2f', [Size]) + ' Б';
  if Size > 1024 then
    Result := Format('%.2f', [Size / 1024]) + ' Кб';
  if Size > 1048576 then
    Result := Format('%.2f', [Size / 1048576]) + ' Мб';
  if Size > 1073741824 then
    Result := Format('%.2f', [Size / 1073741824]) + ' Гб';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  adir, afile: string;
begin
  if SelectDirectory('Выберите каталог', '', adir) then
  begin
    if adir[Length(adir)] <> '\' then
      adir := adir + '\';
    afile := ExtractUrlFileName(link);
    Edit1.Text := adir + afile;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  IdThreadComponent1.Start;
end;

procedure TForm1.IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Int64);
var
  I: Int64;
begin
  if (ASender as TIdHttp).Response.ResponseCode <> 200 then
    Exit;
  ProgressBar1.Position := AWorkCount;
  ProgressBar2.Position := WorkMax - AWorkCount;
  CaptionDownload.Caption := SizeOfFile(AWorkCount);
  CaptionLeft.Caption := SizeOfFile(WorkMax - AWorkCount);
  I := GetTickCount;
  if I > TickCount then
    CaptionSpeed.Caption := SizeOfFile((AWorkCount - BytesCount) *
      (1000 / (I - TickCount))) + '/c';
  BytesCount := AWorkCount;
  TickCount := I;
end;

procedure TForm1.IdHTTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Int64);
begin
  if (ASender as TIdHttp).Response.ResponseCode <> 200 then
    Exit;
  TickCount := GetTickCount;
  BytesCount := 0;
  WorkMax := AWorkCountMax;
  CaptionSizeFile.Caption := SizeOfFile(WorkMax);
  ProgressBar1.Max := WorkMax;
  ProgressBar1.Position := 0;
  ProgressBar2.Max := WorkMax;
  ProgressBar2.Position := WorkMax;
end;

procedure TForm1.IdHTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
  if (ASender as TIdHttp).Response.ResponseCode <> 200 then
    Exit;
  Timer1.Enabled := false;
  IdThreadComponent2.Start;
end;

procedure TForm1.IdThreadComponent1Run(Sender: TIdThreadComponent);
var
  Stream: TFileStream;
  Http1: TIdHttp;
begin
  CaptionTime.Caption := '00:00:00';
  Timer1.Tag := 0;
  Timer1.Enabled := true;
  Stream := TFileStream.Create(Edit1.Text, fmCreate);
  Http1 := TIdHttp.Create(nil);
  Http1.HandleRedirects := true;
  Http1.OnWorkBegin := IdHTTP1WorkBegin;
  Http1.OnWork := IdHTTP1Work;
  Http1.OnWorkEnd := IdHTTP1WorkEnd;
  try
    Http1.get(link, Stream);
  except
    if IdThreadComponent1.Terminated then
      Exit;
    Sender.Synchronize(messageerror);
    Stream.Free;
    Http1.Free;
    Timer1.Enabled := false;
    IdThreadComponent1.Stop;
    Exit;
  end;
  Stream.Free;
  Http1.Free;
  IdThreadComponent1.Stop;
end;

procedure TForm1.IdThreadComponent2Run(Sender: TIdThreadComponent);
begin
  Sender.Synchronize(messageok);
  IdThreadComponent2.Stop;
end;

procedure TForm1.messageerror;
begin
  ShowMessage('Ошибка');
end;

procedure TForm1.messageok;
begin
  ShowMessage('Файл загружен');
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  ss, mm, hh: string;
begin
  Timer1.Tag := Timer1.Tag + 1;
  ss := Format('%.2u', [Timer1.Tag mod 60]);
  mm := Format('%.2u', [(Timer1.Tag div 60) mod 60]);
  hh := Format('%.2u', [(Timer1.Tag div 3600) mod 24]);
  CaptionTime.Caption := hh + ':' + mm + ':' + ss;
end;

end.

Последний раз редактировалось fudihet; 01.02.2015 в 11:37.
fudihet вне форума Ответить с цитированием
Старый 31.01.2015, 17:48   #2
lomastr_
Форумчанин
 
Регистрация: 16.01.2015
Сообщений: 672
По умолчанию

к вкл из потока обращаться нельзя
lomastr_ вне форума Ответить с цитированием
Старый 31.01.2015, 18:40   #3
fudihet
Новичок
Джуниор
 
Регистрация: 31.01.2015
Сообщений: 10
По умолчанию

а можете показать что именно изменить нужно?

как я понял ошибка где-то тут:

Код:
ProgressBar1.Position := AWorkCount;
ProgressBar2.Position := WorkMax - AWorkCount;
CaptionDownload.Caption:=SizeOfFile(AWorkCount);
CaptionLeft.Caption:=SizeOfFile(WorkMax - AWorkCount);
потому что если закоментировать файл загружается нормально, но как исправить эту ошибку?

Последний раз редактировалось Stilet; 01.02.2015 в 10:22.
fudihet вне форума Ответить с цитированием
Старый 01.02.2015, 13:01   #4
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Попробуй пройти по этим четырём строкам с помощью BreakPoint
Shouldercannon вне форума Ответить с цитированием
Старый 01.02.2015, 13:14   #5
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Чего там идти-то? Что он увидеть может?
Нельзя из не UI потока обращаться к UI элементам, надо как-нибудь синхронизироваться. Например, TThread.Synchronize
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 01.02.2015, 13:15   #6
lomastr_
Форумчанин
 
Регистрация: 16.01.2015
Сообщений: 672
По умолчанию

Цитата:
как я понял ошибка где-то тут:
потому что #2
у вас загрузка в доп. потоке, а тут вы свойства контролов меняете, и без синхронизации
lomastr_ вне форума Ответить с цитированием
Старый 01.02.2015, 13:36   #7
fudihet
Новичок
Джуниор
 
Регистрация: 31.01.2015
Сообщений: 10
По умолчанию

т.е. как то так нужно синхронизацию сделать?

Код:
   Synchronize(
      procedure
      begin
  ProgressBar1.Position := AWorkCount;
  ProgressBar2.Position := WorkMax - AWorkCount;
  CaptionDownload.Caption := SizeOfFile(AWorkCount);
  CaptionLeft.Caption := SizeOfFile(WorkMax - AWorkCount);
 end);
только не работает почему то...
fudihet вне форума Ответить с цитированием
Старый 01.02.2015, 14:26   #8
fudihet
Новичок
Джуниор
 
Регистрация: 31.01.2015
Сообщений: 10
По умолчанию

как сдесь правильно синхронизацию сделать? Я просто раньше не работал с потоками.
fudihet вне форума Ответить с цитированием
Старый 01.02.2015, 14:36   #9
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Код:
type
  TMyThread = class(TThread)
  private
    { Private declarations }
    i: Integer;
  protected
    procedure Execute; override;
    procedure SyncProc;
  public
  end;

var
  FormMain: TFormMain;
  MyThread: TMyThread;

implementation

{$R *.dfm}

procedure TFormMain.BStartClick(Sender: TObject);
begin
  MyThread := TMyThread.Create(True); // После создания поток остановлен
  MyThread.FreeOnTerminate := True; // После завершения работы поток "умрёт" сам
  MyThread.Resume; // Запуск потока
end;

procedure TMyThread.Execute;
var
  i2: Integer;
begin
  for i2 := 0 to 60 do
  begin
    if i2 > 61 then Break;
    Sleep(100);
    i := i2;
    Synchronize(SyncProc);
  end;

  Terminate;
end;

procedure TMyThread.SyncProc;
begin
  FormMain.Caption := IntToStr(i);
end;
...
Код:
procedure TMyThread.SyncProc;
begin
  FormMain.ProgressBar1.Position := AWorkCount;
  FormMain.ProgressBar2.Position := WorkMax - AWorkCount;
  FormMain.CaptionDownload.Caption := SizeOfFile(AWorkCount);
  FormMain.CaptionLeft.Caption := SizeOfFile(WorkMax - AWorkCount);
end;

Последний раз редактировалось Shouldercannon; 01.02.2015 в 14:39.
Shouldercannon вне форума Ответить с цитированием
Старый 01.02.2015, 14:55   #10
fudihet
Новичок
Джуниор
 
Регистрация: 31.01.2015
Сообщений: 10
По умолчанию

Shouldercannon, не совсем понятно как это использовать в моем случае?
fudihet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Nero - ошибка драйвера DMA. ошибка CRC NecRoMat Софт 5 09.05.2012 01:29
Где ошибка в этом исходном коде на языке Си? Или ошибка в Excel? ArchiCurtis Помощь студентам 2 07.04.2012 14:16
Ошибка run-time Error 1004 общая ошибка ODBC kaval88 Microsoft Office Excel 0 27.02.2011 20:20
Ошибка в коде, ошибка в css или это проблема с совместимостью с браузерами? ankris HTML и CSS 5 23.11.2010 16:58
Это ошибка Delphi или моя ошибка??? bloodeagle Общие вопросы Delphi 3 12.11.2009 15:26