Главная страница
    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
1-13206
Alexkr
2003-05-27 10:20
2003.06.05
Куда поместить двоичный файл?


1-13254
AlexT1000
2003-05-23 14:15
2003.06.05
как HTM файл с картинками отправить по почте?


6-13362
Sliski Slimak
2003-03-03 18:58
2003.06.05
Сетевой телефон


4-13523
sosv
2003-04-07 11:56
2003.06.05
Как отлавливать нажатия мыши вне окна моего приложения?


3-13045
Silver_
2003-05-16 16:46
2003.06.05
нельзя редактировать Detail5ADODataSet 5-го(!) уровня почему?





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