Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.05;
Скачать: [xml.tar.bz2];

Вниз

длительные процессы и ProgressBar   Найти похожие ветки 

 
qwerty2   (2003-05-21 18:49) [0]

При выполнении какого нибудь проолжительного действия например выполнение запроса нужно отобразить ProgressBar с произвольно движущимся указателем. Как этого можно добится ведь весь процесс занят выполнением запроса и никакие другие события (например OnTimer) не срабатывают?


 
Юрий Зотов   (2003-05-21 18:51) [1]

Запускаете продолжительное действие в отдельном потоке, при этом ProgressBar работает в основном.


 
Переяслов Григорий   (2003-05-21 19:04) [2]

А ProcessMessages в цикле запроса не поможет?


 
Юрий Зотов   (2003-05-21 19:09) [3]

Поможет. Если у запроса есть цикл.
:о)


 
qwerty2   (2003-05-22 10:56) [4]

А как можно сделать, чтоб этот отдельный поток уведомил основной, что он завершился? например
procedure TForm1.Button1Click(Sender: TObject);
...
Form1.Timer1.Enabled:=true;
thr1:=thr.create;// поток в котором происходит длительное действие
...// действия которые нужно выполнить только когда поток завершится ...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+2;//во время выполнения потока движется указатель Progressbara
end;



 
qwerty2   (2003-05-22 10:56) [5]

А как можно сделать, чтоб этот отдельный поток уведомил основной, что он завершился? например
procedure TForm1.Button1Click(Sender: TObject);
...
Form1.Timer1.Enabled:=true;
thr1:=thr.create;// поток в котором происходит длительное действие
...// действия которые нужно выполнить только когда поток завершится ...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form1.ProgressBar1.Position:=Form1.ProgressBar1.Position+2;//во время выполнения потока движется указатель Progressbara
end;



 
Юрий Зотов   (2003-05-22 10:58) [6]

F1 - TThread.OnTerminate.


 
qwerty2   (2003-05-22 23:12) [7]

И опять проблема...
я в отдельном потоке выполняю открытие некоего COM сервера (напр. Worda) которое занимает много времени а пользователю пустить ProgressBar
и что удмвительно:
в момент выполнения этой строчки CreateOleObject("Word.Application"); происходит ошибка времени выполнения - Не был произведен вызов CoInitialize. То же самое если использовать раннее связывание и явный вызов того самого CoInitialize.
вот полный текст программы
unit UniThr;
interface
uses
Windows, Messages, ComObj, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
ProgressBar1: TProgressBar;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
public
end;

type thr=class(TThread)
constructor create;
public
procedure Execute; override;
procedure SPr;
procedure ProcThr;
end;

var
Form1: TForm1;
thr2:thr;

implementation
{$R *.dfm}
constructor thr.create;
begin
inherited create(false);
end;

procedure thr.execute;
begin
spr;
end;

procedure thr.SPr;
begin
ProcThr;
end;

procedure thr.ProcThr;
var i,j,x:integer;
vv:variant;
begin
x:=0;
CreateOleObject("Word.Application");
for i:=0 to 100000 do
for j:=0 to 25000 do
inc(x);
Form1.Edit1.Text:=inttostr(x);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Timer1.Enabled:=true;
thr2:=thr.create;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Progressbar1.Position:=Progressbar1.Position+5;
end;
end.

Ошибки не возникает если вызов ProcThr обернуть в synchronize. Но желанный эффект с ProgressBarом при этом конечно же больше не наблюдается.


 
Тих   (2003-05-22 23:28) [8]

В CoInitialize(0) надо вызывать в конструкторе потока.




 
AbrosimovA   (2003-05-23 11:19) [9]

В своей программе я пользуюсь компонентом Gauge, но суть задачи
была такая же, как и у qwerty2. Когда я считывал большие объемы
данных из файла и записывал их в таблицу Excel, то видел что
часы в программе(в основной форме) останавливались, а это выглядело не очень.
Для решения этой проблемы, я создал отдельную форму под именем GaugeForm с Gauge посередине.

Для чтения данных из файла:

procedure TMainForm.ReadClick(Sender: TObject);
begin
GaugeForm.Caption:="Чтение данных из файла";
GaugeForm.Gauge1.Progress:=0;
GaugeForm.Show;
GaugeForm.Update; //Без Update на экран всплывает окно без Gauge
MainForm.Hide;//Скрываю гланую форму
ReadDataFromFile; //Длительн. процедура чтения данных из файла
Flag:=true;//Разрешить запись в Excel
SplashForm.Hide;
MainForm.Show;
end;


Для записи в Excel:

procedure TMainForm.SaveClick(Sender: TObject);
begin
GaugeForm.Caption:="Создание документа";
GaugeForm.Gauge1.Progress:=0;
GaugeForm.Show;
GaugeForm.Update;
MainForm.Hide;
SaveDataToExcel;//Длительн.процедура записи данных в Excel
GaugeForm.Hide;
MainForm.Show;
end;


Так как при чтении(или записи) выполняются только процедура ReadDataFromFile(или SaveDataToExcel) и таймеры стоят, то
формирование процента выполненной работы и заливки Gauge я запихал именно в работающую в данный момент процедуру.

Если логика будет не совсем понятна, то пиши.


 
Boris K.   (2003-05-23 17:13) [10]

Я почти так же сделал в своей программе - вызывается процедура копирования огромного файла, и в ней после BlockRead обновляется Gauge... Но! Пока читается блок - всё замерло. Эту проблему никак не побороть? (просьба - "Application.ProcessMessages" и change "BlockSize" не предлагать !!!) :)


 
AbrosimovA   (2003-05-26 11:10) [11]

Привожу кусочек кода чтения из файла, в котором идет также формирование процентов для Gauge и все работает:

procedure FileParam;
begin
FullPath:=Dir+"\"+NameFile;
AssignFile(FTrnH,FullPath);
Reset(FTrnH,1);
BlockRead(FTrnH, H, SizeOf(H), Count);
SizeB:=H.SizeBlock;
SizeTr:=H.SizeTrend;
end;

function TMainForm.Gauge(I: integer):integer;
begin
SplashForm.Update;
Inc(Progr);
Inc(S);
Result:=(S+1)*G;
SplashForm.Gauge1.Progress:=Progr;
end;

procedure TMainForm.ReadValue;
var I,J,K: integer;
begin
Value1:=TStringList.Create;
Value1.Clear;
FileParam;
G:=Round(0.01*SizeTr);
M:=G;
S:=0;
for J:=0 to SizeTr-1 do begin
BlockRead(FTrnH, V, H.SizeRec, Count);
for I:=1 to SizeB do begin
Str2:=IntToStr(I)+") "+FloatToStrF(V.ValuePar[I],
ffFixed,8,2);
Value1.Add(Str2);
end;
if J=M then M:=Gauge(J);
end;
CloseFile(FTrnH);
end;




Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.06.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.008 c
3-13069
KIR
2003-05-13 15:52
2003.06.05
Похоже грохнулся IB. Может, кто знает, как чинить. Вот что пишет:


1-13263
gRad2003
2003-05-23 19:38
2003.06.05
Delphi -> C++


1-13312
Кен
2003-05-23 03:25
2003.06.05
А нет ли такой функции, чтобы преобрзовывать class в string ?


14-13422
Holy
2003-05-19 13:07
2003.06.05
Использовать ли классы


1-13119
Test
2003-05-25 18:06
2003.06.05
HOWTO WriteLn в консоле цветом сделать?





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