Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Embarcadero RAD Studio XE4

Автор: HeMet
Дата сообщения: 15.08.2013 19:00

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

Весь гуй работает в основном потоке, и на всё приложение одна очередь сообщений.
Где-то видел примеры, как народ правил TApplication что бы от этого уйти.
Автор: LGTeam
Дата сообщения: 15.08.2013 22:12
AlekXL, посмотрите, может навеет что:
https://code.google.com/p/omnithreadlibrary/
Автор: Eternal_Shield
Дата сообщения: 15.08.2013 22:24
AlekXL

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

Ага.

HeMet

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

Насколько я понимаю, винда постит сообщения в поток, где создан объект. Достаточно добавить обработку сообщении в том потоке, где создан объект и всё. Никогда этой фигнёй не занимался, но, по идее, всё именно так и работает.
Автор: Arioch1
Дата сообщения: 15.08.2013 22:53
Есть еще вариант через 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 ?
Автор: deks
Дата сообщения: 16.08.2013 12:28
Arioch1
AlekXL

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

Если при создании формы делается фоновая работа, так проще быстро создать форму (контролья быстро инициализируются в пустом состоянии), потом делать фоновые задачи (отлично это делает OmniThreadLibrary) в другом потоке по подготовке данных (в FMX можно даже анимашку повесить на заргурзку данных - крутящиеся точечки), а в главный поток говорить про прогресс в выполнении фоновой задачи! В OmniThreadLibrary есть куча примеров такой работы - причем и с передачей сообщений о прогресе, и с передачей в фоновый поток начальных данных, и с загрузкой результата фоновой обработки, и с параллельным разбиением задачи на несколько потоков для одновременной обработки..
Автор: Eternal_Shield
Дата сообщения: 16.08.2013 12:32

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

rly? имхо, тут главная проблема в Dispatcher approach для гуя в винде ...
Автор: Arioch1
Дата сообщения: 16.08.2013 12:48

Цитата:
В 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 не модуальное и делать отдельное крохотное окно модальное не хочется.
Автор: X11
Дата сообщения: 16.08.2013 13:17
for i := 1 to 1000000 do begin

Долгая-муторная-работа(i);

Label2.Caption := IntToStr(i) =' из 1000000';
application.processmessages
end;

Добавлено:
а ещё можно попробовать BeginThread http://www.delphibasics.ru/BeginThread.php
Автор: Arioch1
Дата сообщения: 16.08.2013 14:25
Я не собираюсь вызывать Долгая-муторная-работа(i);
Я как раз хочу это отдать OTL и забыть: мне нужно не вынести обработку в отдельный поток (как ты предлагаешь), а РАСПАРАЛЛЕЛИТЬ по количеству процессоров/ядер


Код: TForm1.Button1Click;
begin
Label1.Caption := ' Ждите, работаем ';

for i := 1 to 1000000 do begin

Долгая-муторная-работа(i);

Label2.Caption := IntToStr(i) =' из 1000000';

end;
Label1.Caption := 'Сделали';
end;
Автор: AlekXL
Дата сообщения: 16.08.2013 19:55
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();
Автор: Arioch1
Дата сообщения: 17.08.2013 02:41

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


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


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

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

Не убедительно
Автор: kiddo95
Дата сообщения: 17.08.2013 09:24
Как сделать так, чтобы если юзер нажал кнопку Х(кнопка, закрыть, та которая во всех прикладных программах присутствуют, даже в браузерах) или выключил компьюер, не сохранялись действия пользователя. Кучу форумов перерыл, не могу найти решение.
Автор: MGAlex
Дата сообщения: 17.08.2013 10:34
kiddo95
Не сохранялись где?
Автор: kiddo95
Дата сообщения: 17.08.2013 10:43
MGAlex, в базе данных MS Access.
Автор: LGTeam
Дата сообщения: 17.08.2013 11:12
kiddo95, почитайте про транзакции..
например при старте: ADOConnection1.BeginTrans;
а на закрытие применяете изменения через: ADOConnection1.CommitTrans;
или отменяете: ADOConnection1.RollbackTrans;
Автор: MGAlex
Дата сообщения: 17.08.2013 11:14
kiddo95
Вопрос, по-моему, не в той теме.
С базой Access не работал, но в других БД, с котороми работал и работаю, в частности Interbase, Yaffil, FireBird, Paradox данные не сохраняются, если их не записать.
Автор: AlekXL
Дата сообщения: 17.08.2013 17:51

Цитата:
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, да только в реальном мире задачи не столь однотипные. Там не массив задач, а иерархия.
Моя цель была сделать свое приложение максимально многопоточным, чтобы все приложение было как иерархия задач, и каждая каждая задача могла работать в произвольном потоке.
Да, это самоцель. Реально такое может понадобиться только убер-сложному и убер-критичному ко времени исполнения приложению. Но через некоторое время я смогу сказать : я сделал это. Я умею.
Автор: Mikanoshi
Дата сообщения: 17.08.2013 19:50
Непонятно зачем RTTI теперь неубирающийся сделали, почти 400 кило, один из самых больших юнитов в exe. Я не использую RTTI и вообще только в теории смутно представляю зачем это нужно, дак нет, начиная с XE3 он пихается в экзешник намертво.
Автор: MGAlex
Дата сообщения: 17.08.2013 20:36
Mikanoshi
Для солидности
Автор: Mikanoshi
Дата сообщения: 17.08.2013 20:53
Экзешник в ХЕ2 в 1.5 раза меньше, солидно, ничего не скажешь)
Если для своей проги это пофиг, то для dll-плагинов, которые я пишу для RnQ (маленькая ася!), это ппц. Они по 3 метра получаются, да вся RnQ без UPX весит 5
Автор: MGAlex
Дата сообщения: 17.08.2013 21:07
Mikanoshi
RnQ - это мой любимый ICQ-клиент. По-моему, это лучший клиент в своем роде. Сам exe-файл R&Q весит 1,05 Мб.

Полностью согласен по поводу увеличения объема exe-шника.

Вот в MS Office с новым форматом docx, xlsx и т.д. размер файла стал меньше, чем doc, xls и др. И это показатель, на мой взгляд.
Автор: Mikanoshi
Дата сообщения: 17.08.2013 21:25

Цитата:
Сам exe-файл R&Q весит 1,05 Мб.

Без UPX 3.6, а 64-бит версия, скомпилированная в новых делфях, уже почти 6 метров) Прогресс, ничего не скажешь. Такими темпами слоган придётся менять на "аська средненького размера " ^_^
Автор: MGAlex
Дата сообщения: 17.08.2013 21:52
Честно говоря, мне не очень понятно, зачем R&Q 64-бит версия. Ясное дело, что из-за этого еще больше размер становится.
Автор: Mikanoshi
Дата сообщения: 17.08.2013 23:39
Ну 21 век, скоро всё будет 64-битное, так что всё равно придётся. Я сам на 32 сижу, т.к. 64 глючная и есть версия только R&Q Multi (OBIMP + MRA + XMPP), а мне эти протоколы нафиг не нужны.

И конечно плагины, я свои смогу переписать, но другие уже заброшены и никто их не переделает, только если писать для них 32-битную OOP обёртку. Мне же главным образом от 64 версии нужен интерфейс, т.к. у меня шелл bbClean x64 вместо explorer.exe, и скины он применяет только на 64-битные приложения))
Автор: MGAlex
Дата сообщения: 18.08.2013 00:19

Цитата:
Ну 21 век, скоро всё будет 64-битное, так что всё равно придётся.

Скоро - понятие относительное. 64-битный компилятор не так давно появился, особенно в С++ Builder.
Автор: AlekXL
Дата сообщения: 18.08.2013 00:24

Цитата:
Непонятно зачем RTTI теперь неубирающийся сделали

WEAKLINKRTTI .

Добавлено:

Цитата:
скоро всё будет 64-битное

а зачем? Работа 32-разрядном режиме поддерживается аппаратно. И будет поддерживаться еще очень долго(10лет минимум)

32-разрядное приложение кушает меньше ресурсов. Более того, оно не способно, без специальных хаков, забрать у системы больше 2гб памяти, даже если "протекает". Плюс, дельфи приложения, как говорят, работают 32-разрядном режиме быстрее(это неверно для тяжерой FP арифметики)

---
кстати, кто нибудь замерял скорость integer vs NativeInt арифметики в 64-разрядном режиме? Особенно если не слишком нажимать на тяжелые операции вроде IDIV(тут, ежу понятно, 32 разрядные целые шустрее)
Автор: Mikanoshi
Дата сообщения: 18.08.2013 01:04

Цитата:
WEAKLINKRTTI

Да я даже больше скажу)

Код: {$SETPEFlAGS IMAGE_FILE_DEBUG_STRIPPED or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED}
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
Автор: ValidolX
Дата сообщения: 18.08.2013 08:52

Цитата:
И будет поддерживаться еще очень долго(10лет минимум)

ой ли, сегодня если попадется PE NE то одно на сотню, вполне вероятно что скорее
Автор: LGTeam
Дата сообщения: 18.08.2013 10:02
есть ли у кого переделанная DSpack под XE4 64 бита?
Автор: MGAlex
Дата сообщения: 18.08.2013 10:16

Цитата:
И будет поддерживаться еще очень долго(10лет минимум)

Тоже так считаю. 64-бит нужно для программ, которым нужны большие ресурсы памяти.
Вот, например, выше приведенной аське R&Q ну никак не нужны большие ресурсы. Да и куче других программ тоже.

Страницы: 1234567891011121314151617181920212223242526

Предыдущая тема: cxDBPivotGrid выгрузка в excel


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.