|
|
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Ну на Delphi примерно так: var ProvOptions: TGetRecordOptions; DataPacket: OleVariant; ProvOptions := [grMetadata, grReset]; DataPacket := dspOut.GetRecords(-1,RecsOut,Byte(ProvOptions)); Опции - как надо, а TDatasetProvider (dspOut), ессно, должен быть присоединен к датасету. Все, данные (и метаданные!) - в переменной, теперь просто из потока через Syncronize остается присвоить DataPacket свойству TClientDataset.Data в основном потоке, и сделать ей Active := true. Можно и частями данные передавать, но это уже в хелпе посмотри :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2003, 12:37 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Сорри, наверное запутанно объяснил 1) На форме например объявлено Q:TIBQuery. Ты его юзаешь во втором потоке. Так вот в первом потоке не рекомендую обращаться к Q. 2) Очередь придется писать свою, о чем я и пытаюсь сказать уже в трех мессагах :)). Написать ее не составляет труда, это обычная лаба в любом вузе. А вот тонкости синхронизации. Вобщем предложу еще раз посмотреть код моей :)) Не уверен что будет проще то что предлагает Roman Ignatiev ... В том что я предлагаю, ты можешь на форме делать все что угодно. Как в обычном приложении. В тоже время то что предлагается Романом надо будет отдельно отрабатывать для каждого запроса... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2003, 03:17 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
2StarWind Я думаю, ты догадываешься, что приведенный пример не более чем тест. И где ты там предлагаешь ставить Critical Section? Не вопрос, согласен, обработка WM в том же потоке должна решить проблему. Но раньше и речи об этом не было. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2003, 11:47 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Константин Хлопов критическая секция ставится для разграничения доступа к участку кода. так что первый поток вычисляяет значение переменной и в критической секции присваивает это значение в буферную переменную . Второй поток (который оторажает данные) может функционировать например так: через определенное время в критической секции считывает значение из буферной переменной на экран . Вот и все ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2003, 04:11 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Но, насколько я понимаю, не переписывая обработку оконных сообщений сделать этого нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2003, 10:51 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Это можно сделать и более чем просто никаких траблов // код функции вычисления чего-то долгоиграющего ... result:=BigFunct; EnterCriticalSection(CriticalSection); buf:=result; LeaveCriticalSection(CriticalSection); ... // код функции отображения ... EnterCriticalSection(CriticalSection); Label1.Caption:=buf; LeaveCriticalSection(CriticalSection); ... и в чем проблемы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2003, 11:47 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Дышите глубже, пролетаем сочи! :)) Говорю как человек сделавший компонент для доступа к Firebird через потоки. В потоке IBDataBase, IBTransaction, IBDataSet. Как один из входных параметров процедуры запуска потока указатель DataSource (TDataSource) в который надо вернуть данные. DataSource - другой поток, другая форма, общий только процесс. В потоке: подключились, выполнили запрос в Synchronize написали DataSource.DataSet := IBDataSet выполнили Supend; Спокойно работаем через DBEdit, DBGrid и пр. и редактируем данные. При необходимости используем поток повторно. У меня компонент - отдельная бибилиотека (COM объект) поэтому необходимо использовать sharemem. Единственные проблемы c DBGrid, перед перед повторным использованием потока DBGrid.DataSource := nil, после того как поток отработал DBGrid.DataSource := DataSource. Удачи! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2003, 12:38 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
2 StarWind Не спора ради а истины для... Допустим, WM_PAINT приходит в "середине" кода отображения... Сто пудов проблем не будет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2003, 14:14 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
а с какого счастья они будут? WM_PAINT может возникнуть когда угодно и будет прорисовывать данные из своих буферов. Даже если в самй протиыный момент, когда получаем результат функции... так тот результат попадает в буфер, а модуль отображения находится в том же самом потоке что и очередь сообщений.Между собой они разделены критической секцией... Вот и все P.S. Прежде чем ввязываться в спор, нужно разбираться в этом ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2003, 03:09 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Где выполняется код функции отображения? Если в приложении (кроме главного потока) еще только один, я что не имею права в его теле написать Form1->Label->Text = "blabla";? И зачем мне вызывать методы через Synchronize, как не для того, чтобы синхронизироваться с обработкой оконных сообщений в главном потоке? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.12.2003, 10:56 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
EnterCriticalSection(CriticalSection); Label1.Caption:=buf; LeaveCriticalSection(CriticalSection); вот тут отображение, а вот то что ты предложил, так явно сделать нельзя. метод Synchronize... Ну не люблю я класс TThread... Органическое отвращение к нему... Тем более читал в литературе, что в нем есть ряд глюков... Так что юзайте WinAPI CreateThread ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2003, 03:02 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Не надо CreateThread. Это еще хуже. Надо BeginThread, иначе нарветесь, когда исключение возникнет. Кстати, TThread в D6 вполне нормально реализован, и неплохо работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2003, 10:30 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Именно про D6 разговор и велся, конкретно про функцию WaitFor. В пятом (на котором работаю) мне не понравилась реализация метода Terminate. а CreateThread это между прочим WinAPI... И именно через нее все и работает... в том числе и BeginThread. Причем вызывает она напрямую именно эту функцию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2003, 10:36 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
да и еще, исключения нужно вовремя перехватывать, особенн при работе с dll ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2003, 10:37 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Не напрямую, BeginThread делает две вещи: BeginThread encapsulates the Win32 CreateThread API call, but unlike CreateThread, it sets the global IsMultiThread variable, thereby making the heap thread-safe. Thread functions should handle all of their own exceptions. BeginThread sets up an exception frame that allows the system's default exception handler to catch any of the thread's exceptions that have not been handled. Они достаточно важны. А вообще говоря, если можно без потока - надо делать без потока, особенно на клиенте. У меня вообще явно многопоточных клиентов нет. Можно еще использовать COM + ADO, там все вам сделают через интерфейсы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.12.2003, 10:48 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): Integer; var P: PThreadRec; begin New(P); P.Func := ThreadFunc; P.Parameter := Parameter; IsMultiThread := TRUE; Result := CreateThread(SecurityAttributes, StackSize, @ThreadWrapper, P, CreationFlags, ThreadID); end; это ее код ) и что тут высокоинтелектуального? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 03:14 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
а по поводу использовать или нет многопоточник нужно было читать ветку с начала... там весьма веские аргументы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 03:26 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Извиняюсь, что создал ветку и долго не появлялся - был в командировке. Сейчас попытаюсь на основе всех полученных данных и сформировавшейся в голове схемы построить что-нибудь работающее :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 08:58 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
2StarWind Интеллектуального в BeginThread два слова: isMultiThread и ThreadWrapper, эти две вещи и делают то, что написано в справке по BeginThread. Никто не говорит, что нельзя обойтись CreateThread, но тогда уж и мультипоточность сами объявляйте, и все исключения перехватывайте в теле потока. А зачем? Чем меньше пишешь, тем лучше. Многие компоненты работают с потомками TThread, и могу сказать, очень неплохо работают. А вот в необходимости потоков я глубоко сомневаюсь, их вполне можно заменить процессами, иногда это даже проще. И передача данных таблиц между процессами, как и между потоками, не так уж сложна. У меня просто уже давно все визуальные компоненты работают с TClientDataset, и только с ней. Результат - в нее можно передать пакет данных откуда угодно, из файла (можно XML), через Variant, из другого датасета через провайдер. Как я и писал выше, передача через Variant как раз и подходит для межпоточного взаимодействия, сформировал пакет, запомнил в переменной, и через Syncronize его передал прямо в cds в основном потоке. Все, работай дальше. Преимущества? Провайдер сам следит и за транзакцией, и за запросом, ты пишешь несколько строк всего, не особо задумываясь, потоки у тебя или нет. Плюс в cds есть куча маленьких удобств для реализации интерфейса, это и индексация "на лету", и дополнительные поля данных, и возможность отката изменений... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.12.2003, 10:32 |
|
||
|
IBX & TThread
|
|||
|---|---|---|---|
|
#18+
Все исключения и так у меня перехватываются (их попросту некому показывать на консоли сервера) да и вообще они должны перехватываться, чтобы не вгонять юзера в ступор непонятными фразами. Индикатор многопоточности... так я это и сам знаю , а VCL у меня работает в однопоточном режиме и так :)) Заменять процессами.... контекст процесса гораздо больше чем контекст потока и соответственно время на переключение так же. Синхронизация процессов несоизмеримо медленее синхронизации потоковну и плюс к тому общая память и соответственно обмен данными. Между процессами тоже можно подобное сделать, но это не так удобно и главное это медленно. Ну и последний довод. Если в windows есть понятие потока, значит он эффективнее, если приложение подразумевается как многопоточное, чем "многопроцессовое" приложение. Кстате, есть операционки где потоки отстутствуют как класс. Например QNX. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2003, 11:00 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32361727&tid=1579437]: |
0ms |
get settings: |
5ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
204ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
32ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 503ms |

| 0 / 0 |
