| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > ProgressBar при загрузке TTable |
| Автор: NiJazz 8.4.2004, 07:32 |
| Как можно в засисимости от количества записей в таблице "показать" загрузку с помощью PgoressBar? То есть чем больше записей, тем медленнее ползунок... |
| Автор: Cashey 8.4.2004, 08:51 | ||
| Странный вопрос Ну делай цикл
|
| Автор: gray_k 8.4.2004, 08:53 | ||
Нет, так нельзя. Надо оценить время открытия таблицы заранее. Открывать её в отдельном потоке, а в основном потоке запускать ProgressBar. |
| Автор: Cashey 8.4.2004, 09:12 | ||
А зарание никак. В процесс открытия то же вряд ли можно влезть. Можно только сначало открыть таблицу и засечь время
А потом иммитировать открытие таблицы и показать ProgressBar тем способом, который я уже приводил |
| Автор: Maverick 8.4.2004, 09:53 | ||
Странный подход, я бы сказал.... По-моему, действительно дело в обработке потоков.... |
| Автор: Cashey 8.4.2004, 10:51 |
| Maverick ну и как предлогаешь влезть в поток? И потом, для работы ProgressBar, нужно что-то принять за 100%, а как ты собираешься узнать сколько время будет загружаться таблица, до того момента как она загружена? Это все равно, что сказать как закончится матч РОССИЯ-ПОРТУГАЛИЯ прямо сейчас, не дожидаясь пока матч начнется. |
| Автор: Maverick 8.4.2004, 11:12 | ||
| Cashey Я просто в шоке.... я счас попробовал - действительно работает.... но как? почему?
Почему движения Bar зависят от степени открытия таблицы - я не вижу здесь связи в коде..... я скорее не поверю собственным глазам.... Совершенно посторонняя переменная i контролирует Bar.... Что тормозит Bar от мгновенного пробега? Загруженность процессора? Переключение между процессами открытия таблицы и отрисовкой позиции Bar? Значит, все равно потоки косвенно? |
| Автор: x77 8.4.2004, 11:15 |
| с таблицами это не получится. с запросами - можно, только не со всеми субд. у запросов есть метод Fetch и свойство (PacketSize, кажется, не помню) отвечающее за кол-во профетчиваемых записей. вот там можно в цикле профетчить все записи, сопровождая это дело беганьем прогрессбара. а варианты с "предугадыванием времени" - это отстой. время зависит и от процессора, и от скорости обращения к винту, и от объёма свободной памяти, и от размера базы, а для сетевых БД - ещё и от пропускной способности сети и загруза её в данный момент. тут запаришься угадывать. |
| Автор: Maverick 8.4.2004, 11:19 |
| Работает.... Законектился с сервером, именно Table, выбрал таблицу покрупнее - все отработало и Bar как ручной сделал все..... Я сам вот сижу и думаю как? |
| Автор: gray_k 8.4.2004, 12:04 |
| Да блин не может это работать. Этот код делает совсем не то, что прдполагается в топике. Народ, почитайте об отображении визуальной информации из наборов данных, почитайте ФАК в конце концов, не зря же Вит писал. После открытия таблицы RecordCount не даст правильного количества выбранных записей, если не был сделан FetchAll. Получается, что сначала НД открыли, а потом пробегаете по его записям. А надо то отобразить время открытия НД. А если ваш Table.Active будет отрабатывать минуты 2, а с БДЕ такое возможно, я сталкивался? А оценить время открытия *приблизительно) можно. ТОлько здесь общего решения нет. Для каждого вида запроса и движка БД решение своё. |
| Автор: x77 8.4.2004, 12:14 |
| Maverick, что у тебя работает? gray_k, я не знаю, кто что писал, а делается это в два этапа: выполняем запрос вида select count (*) from ...., этот запрос отработает на порядки быстрее любого другого, узнаём из него кол-во записей, потом запускаем сам запрос, уже не count (*), а перечисление полей по-честному (есс-но, с теми же from, where, etc.). после этого открываем запрос и фетчим его потихоньку. кол-во записей, кторое всего придётся фетчить - известно. есстественно, что с ущербной бде это не работает. а в ado, midas, даже в том же ibx - за милую душу. |
| Автор: gray_k 8.4.2004, 13:23 |
| Да, если сначала послать запрос на count(*), то работать будет, про это я не подумал А ты не оценивал, насколько изменится скорость выполнения коде, если после Open сразу сделать FetchAll и если фетчить по одной записи? Просто интересно. |
| Автор: x77 8.4.2004, 13:49 | ||
gray_k, всё зависит от способа доступа. в ADO в этом плане много вкусного - асинхронный фетч, масса настроек и т.д. в ibx и TClientDataset - всё немного попроще, но тоже забавно. по скорости - впечатление слишком субъективное
а всякие там прогрессбары - цыганское великолепие. |
| Автор: Maverick 8.4.2004, 14:04 | ||
| Значит так.... Я тоже был уверен, что не сработает.... Кинул на форму Table, DataSource, Grid, Progressbar и кнопку..... Все обычное - BDE.... Table подключил к серверу Informix к очень большой таблице.... На клик кнопки повесил указанный Cashey код.... прямо скопировал, не менял.... вот это
Запустил, нажал на кнопку - ProgressBar начал постепенно (!) , равномерно заполняться... Когда заполнился весь - в Grid появилась таблица.... Я сам ОФИГЕЛ, но это факт.... я согласен со всем вами сказанным, это не должно работать.... Я до сих пор не могу понять как.... Я уже много раз запускал и ОФИГИВАЛ.... |
| Автор: x77 8.4.2004, 14:34 | ||
Maverick, офигевать тут не с чего абсолютно. убери весь код после Active := TRUE - и твоя таблица откроется мгновенно. и мгновенно профетчится. в коде, который привел Cashey строчка Position:=Round((i/Table1.RecordCount)*100); даёт дикие тормоза. сделай код таким:
и у тебя всё будет летать. а потом откомментируй вон ту строчку с обращением к RecordCount - и получишь тоже самое, что и было. короче говоря, в коде Cashey'я просто исскуственно замедляется проход прогрессбара уже после того, как таблица давно открыта. а пока идёт в цикле обращение к RecordCount - есс-но, записи в гриде не отображаются. Добавлено @ 14:43 в конце концов, поставь после Active := TRUE всего одну строчку: DBGrid1.Update; и ты увидишь значения полей задолго до конца пробега прогрессбара. другой вариант - вставить ProcessMessages - и ты будешь уже гулять по всей таблице, когда прогресбар будет ещё ползти и ползти |
| Автор: Maverick 8.4.2004, 14:44 |
| Да то, что открывается гораздо медленнее я сразу понял.... Я не мог понять, почему цикл влияет на Bar.... Почему не сразу пробегает мгновенно как должно быть.... Неужели RecordCount до такой степени тормозючий? Да не могет быть..... Добавлено @ 14:47 Да и с ProcessMessages я тоже игрался.... Обманули...... |
| Автор: x77 8.4.2004, 14:59 | ||
| Maverick, это вопрос к DbiGetRecordCount и DbiGetExactRecordCount. бде всё тормознючее, увы. разве я тебя обманул? или ты не про меня? не понял эту фразу
|
| Автор: Maverick 8.4.2004, 15:50 |
| |
| Автор: x77 8.4.2004, 16:04 |
| Maverick, |
| Автор: Cashey 8.4.2004, 16:42 |
| x77 Абсолютно верно, если запустить мой код (например, в кнопке) то в гриде записи появятся одновременно с концом работы ProgressBar'а. Вот только это не показатель загрузки таблицы, а мы задерживаем циклом отображение данных в гриде. Вообщем-то можно использовать если надо обмануть пользователя и показать ему "вот видете скока надо ждать" А иначе я вообще не вижу смысла использовать Бар. Я проверил время загрузки таблицы dBase с более чем 15000 записями занимает ок. 60 миллисикунд. ProgressBar имеет смысл использовать только если загрузка больше хотя бы 3-5 сек. И еще x77 твой вариант тоже не идет, я проверил время загрузки Квери и Тэйбла почти одинаково, своим кодом ты обеспечишь 2-х кратную ошибку |
| Автор: Maverick 8.4.2004, 17:03 | ||||
Так надо было уточнить, просили же другое в сабж.... А задержать появление в гриде и движение бара можно и другими, менее тотальными способами...
У меня таблица была в полмиллиона записей - ты обманул меня на полторы минуты.... слишком жестоко даже для среднего пользователя... Добавлено @ 17:04 Я где-то компонент видел соответствующий..... ищу.... Добавлено @ 17:13 не нашел |
| Автор: Akella 20.4.2004, 12:58 |
| А какие типы тиблиц вы используете? Я пробовал на Paradox7 - таблица на 500 тыс записей открывается моментально, и никакого процесса показа не происходит |
| Автор: Maverick 20.4.2004, 14:25 |
| Informix... Жутко загруженный сервер и сеть... |
| Автор: Akella 20.4.2004, 15:59 |
| а может в BDE есть какие-нибудь функции типа Dbi...тыры-пыры? в некорорых программа это ведь реализовано, наверное. |
| Автор: x77 20.4.2004, 16:35 |
| dsergey, в бде - нет. есть левосторонние пакеты, которые работают с теми же dbf без участия бде. и вот в них мне такое встречалось. но навскидку я не помню |
| Автор: Akella 21.4.2004, 08:07 |
| |
| Автор: x77 21.4.2004, 10:42 |
| dsergey, не было смысла. и таблицы и квери, работаеют, по большому счёту, одинаково, разница только в тои, что квери позволяет выполнять запросы. но если ты посмотришь исходники, сами методы организации буфера, доступа к записям, - используют одни и те же процедуры bde, а точнее - dbi. в этом смысле бормановская TQuery представляет собой как бы эмуляцию нормальной квери, но открывается она точно так же, как и таблица. гнусное нае@#$во, в общем. а таблицы открываются влёт, т.к. все записи из базы они не сосут: это происходит только при нажатии, например, Ctrl+End на гриде. смеха ради воткни на форму Table1 и Query1, пропиши для обоих Open, и посмотри, что он запускает. для обоих запускаться будет метод TDataSet.Open, сводящийся к вызову TDataSet.SetActive. он вызовет виртуальный метод InternalOpen, который переопределён в TBdeDataSet, являющимся одним из предков как квери, так и таблицы. все различия между ними связаны с обработкой запросов, парааметров, и пр., а механизм доступа к данным одинаков абсолютно. и заключается этот механизм в буферизованном чтении таблицы, предполагающем мгновенное открытие и подсос по мере надобности. спрашивается, зачем там прогрессбар? тормозить может только обработка сложного запроса, но отобразить это процесс невозможно, т.к. на любом субд он представляет из себя "чёрный ящик", никто не знает, сколько времени он займёт и на каком этапе в данный момент эта обработка находится. а после того, как сам запрос "сгенерён", открытие происходит действительно влёт независимо от кол-ва записей. тормоза при работе с парадоксовскими таблицами как правило вызваны корявостью самого кода, когда при инициализации программы кто-то умный открывает десяток справочных таблиц, связанных между собой десятком лукап-полей, а потом жалуется, какое, дескать, тормознутое бде. а реально, при грамотной организации работы, бде - одна из самых быстрых субд |
| Автор: Akella 22.4.2004, 08:07 |
| То х77 - огромное спасибо за объяснения. |
| Автор: jonik_Dk 23.4.2004, 10:29 |
| Кажись компонентик есть для энтого дела. Добавлено @ 10:38 Нашел как называется : TDBProgressBar, правда версия 2.7 для Delphi5 Так что кому нужно для Delphi 6 и выше можете поискать в Net. Никогда не пользовался этим компонентом - предлагаю не проверенный товар. Если устраивает кого такие условия, могу скинуть |
| Автор: x77 23.4.2004, 14:01 |
| dsergey, это не столько объяснения, сколько рассуждения вслух. ребята, читайте исходники. на ночь, вместо Hustler и Playboy'а. и всё будет классно ;) jonik_Dk, кидай |
| Автор: Akella 23.4.2004, 14:16 |
| кидай ентот компонентик сюда dsermail {at} rambler.ru |
| Автор: jonik_Dk 23.4.2004, 16:27 |
| Я кинул на dsermail@rambler.ru. Если не получишь пиши, не жадный кину еще раз! |
| Автор: x77 23.4.2004, 16:50 |
| на выходных поглядим |
| Автор: jonik_Dk 24.4.2004, 10:28 |
| После просмотра, просьба высказаться как работает компонент. Времени нет даже поставить его, не то чтобы проверить !!! |
| Автор: Akella 26.4.2004, 08:35 |
| Надо было написать, что он для Delphi5. А как его установить для 7-ой версии, например? |
| Автор: x77 26.4.2004, 09:22 | ||
компонент этот юзает стандартные функции бде, в частности, DbiRegisterCallback. смысл её в том, чтобы, например, возвращать процент выполнения большой batch-операции, отменить выполнение квери и др. но я никогда не слышал, чтобы этой функцией можно было выдать процесс выполнения запроса. если интересно, вот копия из справки по бде:
|
| Автор: jonik_Dk 26.4.2004, 09:42 |
| dSergey: Я писал, что компонент для Delphi5, надо быть внимательней. x77: Спасибо, но я противник BDE. Жаль что он работает через BDE. |
| Автор: Akella 26.4.2004, 13:30 |
| Может, кто знает, как установить этот компонент по D7. Этот компонент требует файл Proxies.pas - у кого есть пришлите на dsermail {at} rambler.ru, пожалуйста. |