Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE4

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

Открыть новую тему     Написать ответ в эту тему

AlekXL



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
скажите, а верно ли, что VCL однопоточная? То есть могу ли я создать форму в побочном потоке?

Всего записей: 792 | Зарегистр. 24-04-2008 | Отправлено: 19:49 15-08-2013
HeMet

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
скажите, а верно ли, что VCL однопоточная? То есть могу ли я создать форму в побочном потоке?

Весь гуй работает в основном потоке, и на всё приложение одна очередь сообщений.
Где-то видел примеры, как народ правил TApplication что бы от этого уйти.

Всего записей: 212 | Зарегистр. 05-09-2007 | Отправлено: 20:00 15-08-2013
LGTeam

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
AlekXL, посмотрите, может навеет что:
https://code.google.com/p/omnithreadlibrary/

Всего записей: 46 | Зарегистр. 20-12-2012 | Отправлено: 23:12 15-08-2013
Eternal_Shield

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AlekXL

Цитата:
скажите, а верно ли, что VCL однопоточная? То есть могу ли я создать форму в побочном потоке?

Ага.
 
HeMet

Цитата:
Весь гуй работает в основном потоке, и на всё приложение одна очередь сообщений.  Где-то видел примеры, как народ правил TApplication что бы от этого уйти.

Насколько я понимаю, винда постит сообщения в поток, где создан объект. Достаточно добавить обработку сообщении в том потоке, где создан объект и всё. Никогда этой фигнёй не занимался, но, по идее, всё именно так и работает.

Всего записей: 767 | Зарегистр. 18-05-2009 | Отправлено: 23:24 15-08-2013 | Исправлено: Eternal_Shield, 23:25 15-08-2013
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Есть еще вариант через fibers - но с ним тоже засад много
 
http://andy.jgknet.de/blog/2010/12/using-fibers-for-tab-modal-forms/
http://stackoverflow.com/questions/2618372/delphi-how-to-make-independent-windows
 
 
Насколько понимаю, галвная проблема - что все библиотеки пишутся в рассчёте на один поток.
 
Какой-нибудь DevExpress на все сообщения хуки вешает.
Какой-нибудь VTV свои темы к VCL-ным добавляет.
Были кажется компоненты типа бросаешь его ан форму - и форму можно в PDF сохранять.
Или компонент по переводу формы на другой язык - форм много, а БД одна.
 
И т.д.
 
И вот в такой "общее место" придут одновременно запросы с разных потоков - и что будет? непредсказуемо.
 
Или создаем два окна в разных потоках, а потом одно из них делает ShowModal другому - и получили deadlock.
 
Вы лично так не сделаете? возможно. А ShowMessage ? InpurPrompt? Application.OnException ?

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 23:53 15-08-2013
deks



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Arioch1
AlekXL
 
Arioch1 верно пишет - не стоит связываться с VCL  в разных потоках. А какой смысл это делать? В чем изначальная идея создания формы в другом потоке?  
 
Если при создании формы делается фоновая работа, так проще быстро создать форму (контролья быстро инициализируются в пустом состоянии), потом делать фоновые задачи (отлично это делает OmniThreadLibrary) в другом потоке по подготовке данных (в FMX можно даже анимашку повесить на заргурзку данных - крутящиеся точечки), а в главный поток говорить про прогресс в выполнении фоновой задачи! В OmniThreadLibrary есть куча примеров такой работы - причем и с передачей сообщений о прогресе, и с передачей в фоновый поток начальных данных, и с загрузкой результата фоновой обработки, и с параллельным разбиением задачи на несколько потоков для одновременной обработки..

Всего записей: 857 | Зарегистр. 09-10-2003 | Отправлено: 13:28 16-08-2013
Eternal_Shield

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Насколько понимаю, галвная проблема - что все библиотеки пишутся в рассчёте на один поток.  

rly? имхо, тут главная проблема в Dispatcher approach для гуя в винде ...  

Всего записей: 767 | Зарегистр. 18-05-2009 | Отправлено: 13:32 16-08-2013
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
В OmniThreadLibrary есть куча примеров такой работы - причем и с передачей сообщений о прогресе, и с передачей в фоновый поток начальных данных

 
не хватает главного примера все же.
 
TForm1.Button1.Click;
begin
   Label1.Caption := ' Ждите, работаем ';
 
   for i := 1 to 1000000 do begin
 
        Долгая-муторная-работа(i);
 
        Label2.Caption := IntToStr(i) =' из 1000000';
 
   end;
   Label1.Caption := 'Сделали';
end;
 
И тут оказывается, что Долгая-муторная-работа прекрасно распараллеливается и просто просится в Parallel.Fork.
 
А TForm1 не модуальное и делать отдельное крохотное окно модальное не хочется.

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 13:48 16-08-2013
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
for i := 1 to 1000000 do begin
 
        Долгая-муторная-работа(i);
 
        Label2.Caption := IntToStr(i) =' из 1000000';
 application.processmessages
   end;  
 
Добавлено:
а ещё можно попробовать BeginThread http://www.delphibasics.ru/BeginThread.php

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 14:17 16-08-2013
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Я не собираюсь вызывать Долгая-муторная-работа(i);
Я как раз хочу это отдать OTL и забыть: мне нужно не вынести обработку в отдельный поток (как ты предлагаешь), а РАСПАРАЛЛЕЛИТЬ по количеству процессоров/ядер
 

Код:
TForm1.Button1Click;  
 begin  
    Label1.Caption := ' Ждите, работаем ';  
   
    for i := 1 to 1000000 do begin  
   
         Долгая-муторная-работа(i);  
   
         Label2.Caption := IntToStr(i) =' из 1000000';  
   
    end;  
    Label1.Caption := 'Сделали';  
 end;
перевести на многопоток с минимальными изменениями, типа

Код:
TForm1.Button1Click;  
 begin  
    Label1.Caption := ' Ждите, работаем ';  
   
    Parallel.ForEach(1, 1000000)
       .Execute( Долгая-муторная-работа );  
 
    Label1.Caption := 'Сделали';  
 end;

 
И да, можно добавить монитор сообщений, можно добавлять сигналы-барьеры... но это слишкоммного boilerplate для такой простой задачи.
 
Наиболее простой вариант - сделать фейковую выходную коллекцию и делать цикл по её чтению. А сам поток сделать NoWait плюс NumTasks(CpuCount).
 
Но и это - ugly и посути и по исходнику.

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 15:25 16-08-2013 | Исправлено: Arioch1, 15:31 16-08-2013
AlekXL



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
LGTeam, deks

Цитата:
AlekXL, посмотрите, может навеет что:
https://code.google.com/p/omnithreadlibrary/

 

Цитата:
В OmniThreadLibrary есть куча примеров такой работы - причем и с передачей сообщений о прогресе, и с передачей в фоновый поток начальных данных, и с загрузкой результата фоновой обработки, и с параллельным разбиением задачи на несколько потоков для одновременной обработки..
 

OTL -- зло, я считаю. Во-первых, без нужды завязанное на мессаджи, непереносимое. Скверно, неинтуитивно спроектированное.  
Я уже писал о его грехах. И примеры OTL столь же плохие. В OTL много труда вбухано, но она ужасна, как атомная война.
 
Сейчас этот пшек пытается монетизировать свой опус за счет книги и платных вебинаров. Знаете, если фреймворк настолько неинтуитивен и сложен, что нужна книга, чтобы понять , как все это использовать, то может нафиг его? Зачем связываться с таким безблагодатным поделием?
 
Мне пришлось пилить собственную многопоточку(и очередь тасков не через windows msg queue, а через Collections.TPriorityQueue, нативно) .
 Вот пример ее использования, бутстрап

Код:
 
 fTaskMan:=phGetTaskManager();
 fcBuildCtx:=fTaskMan.Prepare( phClassContext().Build,{$IFDEF DEBUG}'buildClassCtx'{$ENDIF} ).Schedule();
 
 tcInitSettings:= fTaskMan.Prepare(TphSimpleFnMethodTaskImp<IphSettings>.Create(getSettings)
 {$IFDEF DEBUG},'getSettings'{$ENDIF}).Schedule(fcBuildCtx);
 
 fTcGetLocalizer:=TphTaskControlHelper.getGenericTaskControl<IphValuePairs>(GetLocaLizer{$IFDEF DEBUG},'getLocalizer'{$ENDIF}).
      Schedule(tcInitSettings);
 
 tcBootstrapModules :=fTaskMan.Prepare(procedure()begin phBqModule.Bootstrap();end
 {$IFDEF DEBUG},'phBqModule.Bootstrap'{$ENDIF} ).Schedule(tcInitSettings);
 
 fcInitProtocol:=fTaskMan.Prepare(self.InitInternalProtocols {$IFDEF DEBUG}, 'initInternalProtocols'{$ENDIF}).RequireComInitialzation(0).Schedule(tcInitSettings);
 fTcLoadCached:=fTaskMan.Prepare(LoadModuleList{$IFDEF DEBUG},'LoadModuleList'{$ENDIF}).Schedule(fTcGetLocalizer);
 
 fTcScanModules:=fTaskMan.Prepare(TModuleScanner.Create(self) as IphModuleScanner
      {$IFDEF DEBUG},'TModuleScanner'{$ENDIF}).RequireFinished(tcBootstrapBqModules). Schedule(tcInitSettings,ScanDone);
 
 fTcInitVerseList:=fTaskMan.Prepare(
 self.initVerseListEngine{$IFDEF DEBUG},'initVerseListEngine'{$ENDIF}).Schedule(tcInitSettings);
 
 TThread.Yield();
 

уверяю, в отл все это выглядело бы много хуже. (по поводу TThread.Yield.. Хейтер прав, в том, что дельфи потоки запускаются не мгновенно. Они всегда создаются suspended. И запускаются не раньше, чем в AfterConstruction)
 
 
deks

Цитата:
Arioch1 верно пишет - не стоит связываться с VCL  в разных потоках. А какой смысл это делать? В чем изначальная идея создания формы в другом потоке?  

ну я просто интересовался,  не обдумывая это углубленно..  Например, интерфейс для плагина или скрипта, который не умеет работать асинхронно.
 
---
еще вопрос. Оказывается, Halt в Delphi не сразу закрывает приложение, а запускает финализацию юнитов, что  в принципе нежелательно (я использую halt для аварийного останова).
Если кросс-платформенная функция , аналог ExitProcess(1)?

Всего записей: 792 | Зарегистр. 24-04-2008 | Отправлено: 20:55 16-08-2013 | Исправлено: AlekXL, 21:13 16-08-2013
Arioch1



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
если фреймворк настолько неинтуитивен и сложен, что нужна книга, чтобы понять , как все это использовать, то может нафиг его?  

 
Тогда давайте от Delphi один компилятор оставим. RTL, VCL - без документации не разберешься, а раз так, то они просто не нужны.
 

Цитата:
Вот пример ее использования

Т.е. восемь разных команд и столько же переменных разных типов, когда в OTL часто достаточно двух-трех вызовов в одной строке с Code Completion.
 
Не убедительно

Всего записей: 904 | Зарегистр. 03-03-2010 | Отправлено: 03:41 17-08-2013
kiddo95



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Как сделать так, чтобы если юзер нажал кнопку Х(кнопка, закрыть, та которая во всех прикладных программах присутствуют, даже в браузерах) или выключил компьюер, не сохранялись действия пользователя. Кучу форумов перерыл, не могу найти решение.

Всего записей: 11 | Зарегистр. 24-12-2012 | Отправлено: 10:24 17-08-2013
MGAlex



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
kiddo95
Не сохранялись где?

Всего записей: 1855 | Зарегистр. 12-10-2007 | Отправлено: 11:34 17-08-2013
kiddo95



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
MGAlex, в базе данных MS Access.  

Всего записей: 11 | Зарегистр. 24-12-2012 | Отправлено: 11:43 17-08-2013
LGTeam

Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
kiddo95, почитайте про транзакции..
например при старте: ADOConnection1.BeginTrans;
а на закрытие применяете изменения через: ADOConnection1.CommitTrans;
или отменяете:  ADOConnection1.RollbackTrans;

Всего записей: 46 | Зарегистр. 20-12-2012 | Отправлено: 12:12 17-08-2013
MGAlex



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
kiddo95
Вопрос, по-моему, не в той теме.
С базой Access не работал, но в других БД, с котороми работал и работаю, в частности Interbase, Yaffil, FireBird, Paradox данные не сохраняются, если их не записать.

Всего записей: 1855 | Зарегистр. 12-10-2007 | Отправлено: 12:14 17-08-2013 | Исправлено: MGAlex, 12:15 17-08-2013
AlekXL



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
RTL, VCL - без документации не разберешься, а раз так, то они просто не нужны.  

vcl почти гениален по интуитивности и общей архитектуре. Без документации, но с опытом программирования и исходниками, разобраться легко(Недаром WinForms была слизана с VCL).
Про OTL  такого не скажешь.
 

Цитата:
Т.е. восемь разных команд и столько же переменных разных типов, когда в OTL часто достаточно двух-трех вызовов в одной строке с Code Completion.
 
Не убедительно  

там таски зависимые друг от друга. И переменные в основном одного типа IphTaskControl. И можно удалить таск из очереди(чего нельзя сделать в OTL, AFAIK). И треды именуются по имени задачи, выполняемой в данный момент.
 
tcInitSettings зависит от phClassContext().Build(построения контекста delphiSpring)
все остальные прямо или имплицитно зависят от tcInitSettings (то есть он должен быть завершен)
 
fTcScanModules зависит от tcBootstrapBqModules, так и от tcInitSettings  
 
в OTL можно добавить только одну зависимую задачу. Если зависимых несколько, нужно ваять метазадачу, либо писать обработчик завершения, размазывая логику на стопиццот мест в программе, так что кода будет больше, поддерживать его сложнее
 
Более того, если базовая задача завершена, то добавления(ChainTo) зависимой к ней не достаточно(зависимая вообще не запустится), нужно проверять, завершилась ли базовая, и если да, то запускать независимо.
 А проверка статуса  в многопоточном окружении -- требует блокировки. Короче нужно думать, и легко выстрелить себе в ногу. В моей реализации достаточно записать RequireTaskFinished(baseTask). Все! Завершилась ли уже базовая, выпоняется, или только в очереди -- зависимая будет выполнена в надлежащее время.
 
Плюс к тому, нулевая кроссплатформенность из-за Windows Messaging. Тогда как мой код почти всюду ограничивается кроссплатформенным RTL, и нативными коллекциями.  
В отл легко использовать демки паттернов вроде Parallel, да только в реальном мире задачи не столь однотипные. Там не массив задач, а иерархия.  
Моя цель  была сделать свое приложение максимально многопоточным, чтобы все приложение было как иерархия задач, и каждая каждая задача могла работать в произвольном потоке.
Да, это самоцель. Реально такое может понадобиться только убер-сложному и убер-критичному ко времени исполнения приложению. Но через некоторое время я смогу сказать :  я сделал это. Я умею.

Всего записей: 792 | Зарегистр. 24-04-2008 | Отправлено: 18:51 17-08-2013 | Исправлено: AlekXL, 19:04 17-08-2013
Mikanoshi



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Непонятно зачем RTTI теперь неубирающийся сделали, почти 400 кило, один из самых больших юнитов в exe. Я не использую RTTI и вообще только в теории смутно представляю зачем это нужно, дак нет, начиная с XE3 он пихается в экзешник намертво.

Всего записей: 66 | Зарегистр. 13-06-2011 | Отправлено: 20:50 17-08-2013
MGAlex



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Mikanoshi
Для солидности

Всего записей: 1855 | Зарегистр. 12-10-2007 | Отправлено: 21:36 17-08-2013
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Embarcadero RAD Studio XE4


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru