Вопрос

Я хотел бы иметь возможность асинхронно открывать TDataSet в его собственном потоке, чтобы основной поток VCL мог продолжаться до тех пор, пока это не будет сделано, а затем затем читать основной поток VCL из этого TDataSet.Я провел несколько экспериментов и попал в очень странные ситуации, поэтому мне интересно, делал ли кто-нибудь это раньше.

Я видел несколько примеров приложений, в которых TDataSet создается в отдельном потоке, открывается, а затем из него считываются данные, но все это делается в отдельном потоке.Мне интересно, безопасно ли читать TDataSet из основного потока VCL после того, как другой поток откроет источник данных.

Я занимаюсь программированием Win32 в Delphi 7, используя TmySQLQuery из ЦАП для MySQL как мой потомок TDataSet.

Это было полезно?

Решение

Если вы хотите использовать набор данных только в отдельном потоке, вы можете просто использовать синхронизацию для связи с основным потоком для любого обновления VCL/UI, как и с любым другим компонентом.
Или, что еще лучше, вы можете реализовать связь между основным и рабочим потоками с помощью собственной системы обмена сообщениями.

проверьте решение Холлварда для резьбы здесь:
http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html

или вот этот:
http://dn.codegear.com/article/22411

для некоторого объяснения синхронизации и ее неэффективности:
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html

Другие советы

Я видел это в других реализациях TDataSet, а именно в Аста компоненты.Они свяжутся с сервером, немедленно вернутся, а затем вызовут событие после загрузки данных.

Однако я считаю, что это во многом зависит от компонента.Например, те же самые компоненты Asta нельзя было открыть синхронно ни из чего, кроме основного потока VCL.

Короче говоря, я не считаю, что это ограничение TDataSet как таковое, а скорее что-то специфичное для реализации, и у меня нет доступа к упомянутым вами компонентам.

Одна вещь, которую следует иметь в виду при использовании одного и того же Тдатасет между несколькими потоками заключается в том, что в любой момент времени вы можете читать только текущую запись.Итак, если вы читаете запись в одном потоке, а затем вызывает другой поток Следующий тогда у тебя проблемы.

Также помните, что потоку, скорее всего, понадобится собственное соединение с базой данных.Я считаю, что здесь необходим многопоточный «хранящий» объект для загрузки данных из потока в (только запись), которые затем читаются только из основного потока VCL.Перед чтением используйте какой-либо метод синхронизации, чтобы гарантировать, что вы не читаете в тот же момент, когда пишете, или не пишете в тот же момент, когда читаете, или загрузите все в файл памяти и напишите метод синхронизации, чтобы сообщить основному приложению, где в файле нужно хватит читать.

Я использовал последний подход несколько раз, в зависимости от количества ожидаемых записей (и размера набора данных). Я даже перенес его в файл на физическом диске в локальной системе.Это работает довольно хорошо.

Я сделал многопоточный доступ к данным, и это не так просто:

1) Вам необходимо создать сеанс для каждого потока.

2) Все, что делается с этим экземпляром TDataSet, должно выполняться в контексте потока, в котором он был создан.Это непросто, если вы хотите разместить, например.сетка БД поверх него.

3) Если вы хотите, например.основной поток играет с вашими данными, простое решение – переместить их в какой-нибудь отдельный контейнер, например.Набор данных памяти.

4) Вам нужен какой-то механизм сигнализации для уведомления основного потока после завершения получения данных.

...и обработка исключений тоже непростая задача...

Но:Как только вам это удастся, приложение станет действительно элегантным!

Большинство TDatasets не являются потокобезопасными.Я знаю, что потокобезопасен: КБММемтабле.Он также имеет возможность клонировать набор данных, чтобы не возникала проблема перемещения указателя записи (как объяснил Джим МакКит).Это один из лучших наборов данных, которые вы можете получить (купить или бесплатно).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top