Работа с потоками в delphi - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Пользователи Календарь Все разделы прочитаны
Вернуться   Форум администраторов игровых серверов > Полезное / Common > Программирование / Programming

Программирование / Programming
Ищете помощи в написании программы, есть сложность в выполнении задания (в институте и т.д.), пожалуйста, спросите у нас в данном форуме и мы обязательно вам поможем.

Ответ
Опции темы
Непрочитано 22.08.2012, 13:51   #1
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Работа с потоками в delphi

Собственно прошу помощи. Не могу понять в чем примерно дело. Все работает, только вот программа на сохранении виснет. Решил запилить сохранение в поток, дабы не подвисала. В итоге основной поток ждет, пока завершится другой. Если у кого-то есть пример сохранения стрима в потоке - просьба выложить.
Zubastic вне форума Ответить с цитированием
Непрочитано 22.08.2012, 15:04   #2
Олдфаг

По умолчанию Re: Работа с потоками в delphi

Лучше кинуть кусок кода, какой поправить, по описанию ниче не понятно, что где зависает.
G1ta0 вне форума Ответить с цитированием
Непрочитано 22.08.2012, 16:40   #3
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Работа с потоками в delphi

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, StdCtrls, ShellAPI, inifiles, ExtCtrls,
  IdAntiFreezeBase, IdAntiFreeze, Math;

type
  TSaveFile = class(TThread)
  public
    stream:TMemoryStream;
    path:string;
    procedure Execute;override;
    constructor Create(stream:TMemoryStream; path:string);
  end;
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    IdHTTP1: TIdHTTP;
    { Class declarations }
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  ver,
  paths,
  filed:string;

implementation

{$R *.dfm}

procedure TSaveFile.Execute;
begin
 Stream.SaveToFile(path); //сохраняем данные из потока на жестком диске
end;

//Вызов конструктора родительского класса
constructor TSaveFile.Create(Stream:TMemoryStream; path:string);
begin
 inherited Create(True);      //Поток создаем в состоянии «Приостановлен»
 Stream:=Stream;            //Инициализация параметров
 path:=path;
 FreeOnTerminate:=True;       //Поток освободит ресурсы при окончании работы
 Self.Priority:=tpHighest;    //Стартуем с высоким приоритетом
 Resume;                      //Переводим поток в состояние «Активен»
end;

procedure TForm1.Download(obj,path:string);
var Stream:TMemoryStream;
    SaveFile:TSaveFile;
begin
 Stream:=TMemoryStream.Create; //выделение памяти под переменную
 try
  //obj:='http://files-w2.asterios.tm:88/high_five_asterios.7z';
  idHTTP1.Get(obj, Stream); //загрузка в поток данных из сети
  SaveFile:=TSaveFile.Create(stream,path);
  Application.ProcessMessages;
 except
  //
 end;
 Stream.Free; //освобождаем память
end;
Собственно вот. Немного обрезал от мусора
Zubastic вне форума Ответить с цитированием
Непрочитано 22.08.2012, 16:46   #4
Олдфаг

По умолчанию Re: Работа с потоками в delphi

Код:
Self.Priority:=tpHighest;    //Стартуем с высоким приоритетом
Эта строчка от лукавого.

Код:
SaveFile:=TSaveFile.Create(stream,path);
Application.ProcessMessages;
Тебе надо в цикле проверять завершение потока, попустно делая Application.ProcessMessages, чтобы GUI не зависало. Заюзай TEvent.
G1ta0 вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 22.08.2012, 16:56   #5
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Работа с потоками в delphi

G1ta0, я вообще хотел сделать так:
файл скачивается в stream и потом создается thread, который записывает этот stream на диск, а в это время программа качает уже следующий файл
Zubastic вне форума Ответить с цитированием
Непрочитано 22.08.2012, 17:47   #6
Аватар для Hint
Герой

По умолчанию Re: Работа с потоками в delphi

Странная постановка задачи.

Зависает скорее не сохранение, а загрузка файла. Не может файл скачиваться быстрее, чем записываться на локальный диск. Скачку и сохранение надо делать в отдельном потоке с информированием формы через SendMessage. Типа TDownloader.Create('http://example.com/file.zip', 'C:\file.zip', frmMain.Handle). Объект TDownloader в процессе шлет форме сообщения о прогрессе, в случае ошибки и при завершении загрузки.

Цитата:
Тебе надо в цикле проверять завершение потока, попустно делая Application.ProcessMessages, чтобы GUI не зависало. Заюзай TEvent.
Зачем делать новый поток, если основной поток будет в цикле ждать его завершения? При вызове Application.ProcessMessages форма конечно будет перерисовываться, и кнопки будут нажиматься, но по-моему так делать не стоит.
__________________
hLaPEx, Evermore, hAuthD, L2on, ...
Hint вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 22.08.2012, 18:13   #7
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Работа с потоками в delphi

Цитата:
Сообщение от Hint Посмотреть сообщение
Странная постановка задачи.

Зависает скорее не сохранение, а загрузка файла. Не может файл скачиваться быстрее, чем записываться на локальный диск. Скачку и сохранение надо делать в отдельном потоке с информированием формы через SendMessage. Типа TDownloader.Create('http://example.com/file.zip', 'C:\file.zip', frmMain.Handle). Объект TDownloader в процессе шлет форме сообщения о прогрессе, в случае ошибки и при завершении загрузки.

Зачем делать новый поток, если основной поток будет в цикле ждать его завершения? При вызове Application.ProcessMessages форма конечно будет перерисовываться, и кнопки будут нажиматься, но по-моему так делать не стоит.
Подвисает именно сохранение (двигать окошко нельзя).
Я делал через Indy Http тк там можно считать % сколько скачалось и прочее. А потом стрим сохранял на диск.

Добавлено через 5 минут
Цитата:
Сообщение от G1ta0 Посмотреть сообщение
Код:
Self.Priority:=tpHighest;    //Стартуем с высоким приоритетом
Эта строчка от лукавого.
Переделывал под себя, вроде как не влияет..
Цитата:
Сообщение от G1ta0 Посмотреть сообщение
Код:
SaveFile:=TSaveFile.Create(stream,path);
Application.ProcessMessages;
Тебе надо в цикле проверять завершение потока, попустно делая Application.ProcessMessages, чтобы GUI не зависало. Заюзай TEvent.
Файл качается, но на диске или создается файл в 0 метров или же вообще пустота.
Чтобы не зависало использую антифриз.

Последний раз редактировалось Zubastic; 22.08.2012 в 18:19. Причина: Добавлено сообщение
Zubastic вне форума Ответить с цитированием
Непрочитано 22.08.2012, 18:41   #8
Олдфаг

По умолчанию Re: Работа с потоками в delphi

Цитата:
Сообщение от Hint Посмотреть сообщение
Зачем делать новый поток, если основной поток будет в цикле ждать его завершения? При вызове Application.ProcessMessages форма конечно будет перерисовываться, и кнопки будут нажиматься, но по-моему так делать не стоит.
Ясен пень не стоит, но я смотрю на данный кусок кода, там же Stream.Free после создания потока, значит надо ждать пока запишется. Иначе объект, с которым поток работает невалидным будет.
G1ta0 вне форума Ответить с цитированием
Сказали спасибо:
Непрочитано 22.08.2012, 18:47   #9
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Работа с потоками в delphi

Цитата:
Сообщение от G1ta0 Посмотреть сообщение
Ясен пень не стоит, но я смотрю на данный кусок кода, там же Stream.Free после создания потока, значит надо ждать пока запишется. Иначе объект, с которым поток работает невалидным будет.
Вот я хочу, чтобы программа не ждала, а качала следующую часть, сохраняя в фоновом режиме файл.
Код:
procedure TForm1.Download(obj,path:string);
var Stream:TMemoryStream;
    SaveFile:TSaveFile;
begin
 Stream:=TMemoryStream.Create; //выделение памяти под переменную
 try
  //obj:='http://files-w2.asterios.tm:88/high_five_asterios.7z';
  idHTTP1.Get(obj, Stream); //загрузка в поток данных из сети
  SaveFile:=TSaveFile.Create(stream, path);
  SaveFile.Execute;
  Application.ProcessMessages;
 except
  //
 end;
 Stream.Free; //освобождаем память
end;
Если добавляю выделенную строчку, то все работает. Почему иначе не сохраняет (насколько я понял, при создании потока он автоматически начинает выполняться).
Zubastic вне форума Ответить с цитированием
Непрочитано 22.08.2012, 18:54   #10
Олдфаг

По умолчанию Re: Работа с потоками в delphi

Цитата:
Сообщение от Zubastic Посмотреть сообщение
Если добавляю выделенную строчку, то все работает. Почему иначе не сохраняет (насколько я понял, при создании потока он автоматически начинает выполняться).
Stream.Free убери тогда из метода, и поставь в деструктор потока. Ты передаешь объект, который невалиден становится после старта потока.
G1ta0 вне форума Ответить с цитированием
Сказали спасибо:
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сборка Lineage II на Delphi GoodShadow Курилка / Yak floor 12 17.01.2012 21:57
Частичная работа для php программера (работа с веб) niko42 Рынок / Marketplace 13 22.03.2011 13:30
Delphi weTr1k Программирование / Programming 0 13.03.2011 05:18


© 2007–2024 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 14:45. Часовой пояс GMT +3.

Вверх