<p>I'd like to be able to open a TDataSet asynchronously in its own thread so that the main VCL thread can continue until that's done, and then have the main VCL thread read from that TDataSet afterwards. I've done some experimenting and have gotten into some very weird situations, so I'm wondering if anyone has done this before.</p>

<p>I've seen some sample apps where a TDataSet is created in a separate thread, it's opened and then data is read from it, but that's all done in the separate thread. I'm wondering if it's safe to read from the TDataSet from the main VCL thread after the other thread opens the data source.</p>

<p>I'm doing Win32 programming in Delphi 7, using TmySQLQuery from <a href="http://www.microolap.com/products/connectivity/mysqldac/" rel="noreferrer">DAC for MySQL</a> as my TDataSet descendant.</p>

[{'answer_id': 78559, 'author': 'Cyphus', 'author_id': 1150, 'author_profile': 'https://Stackoverflow.com/users/1150', 'pm_score': 2, 'selected': False, 'text': '<p>I have seen it done with other implementations of TDataSet, namely in the <a href="http://www.astatech.com" rel="nofollow noreferrer">Asta</a> components.  These would contact the server, return immediately, and then fire an event once the data had been loaded.</p>\n\n<p>However, I believe it depends very much on the component.  For example, those same Asta components could not be opened in a synchronous manner from anything other than the main VCL thread.</p>\n\n<p>So in short, I don\'t believe it is a limitation of TDataSet per se, but rather something that is implementation specific, and I don\'t have access to the components you\'ve mentioned.</p>\n'}, {'answer_id': 78899, 'author': 'Jim McKeeth', 'author_id': 255, 'author_profile': 'https://Stackoverflow.com/users/255', 'pm_score': 2, 'selected': False, 'text': '<p>One thing to keep in mind about using the same <strong>TDataSet</strong> between multiple threads is you can only read the current record at any given time.  So if you are reading the record in one thread and then the other thread calls <strong>Next</strong> then you are in trouble.</p>\n'}, {'answer_id': 79499, 'author': 'skamradt', 'author_id': 9217, 'author_profile': 'https://Stackoverflow.com/users/9217', 'pm_score': 2, 'selected': False, 'text': '<p>Also remember the thread will most likely need its own database connection.  I believe what is needed here is a multi-threaded "holding" object to load the data from the thread into (write only) which is then read only from the main VCL thread.  Before reading use some sort of syncronization method to insure that your not reading the same moment your writing, or writing the same moment your reading, or load everything into a memory file and write a sync method to tell the main app where in the file to stop reading.</p>\n\n<p>I have taken the last approach a few times, depdending on the number of expected records (and the size of the dataset) I have even taken this to a physical disk file on the local system.  It works quite well.</p>\n'}, {'answer_id': 81129, 'author': 'Francesca', 'author_id': 9842, 'author_profile': 'https://Stackoverflow.com/users/9842', 'pm_score': 4, 'selected': True, 'text': '<p>Provided you only want to use the dataset in its own thread, you can just use synchronize to communicate with the main thread for any VCL/UI update, like with any other component.<br>\nOr, better, you can implement communication between the mainthread and worker threads with your own messaging system.  </p>\n\n<p>check Hallvard\'s solution for threading here:<br>\n<a href="http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html" rel="noreferrer">http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html</a>  </p>\n\n<p>or this other one:<br>\n<a href="http://dn.codegear.com/article/22411" rel="noreferrer">http://dn.codegear.com/article/22411</a>  </p>\n\n<p>for some explanation on synchronize and its inefficiencies:<br>\n<a href="http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html" rel="noreferrer">http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html</a></p>\n'}, {'answer_id': 82002, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>I've done multithreaded data access, and it's not straightforward:</p>\n\n<p>1) You need to create a session per thread. </p>\n\n<p>2) Everything done to that TDataSet instance must be done in context of the thread where it was created. That's not easy if you wanted to place e.g. a db grid on top of it.</p>\n\n<p>3) If you want to let e.g. main thread play with your data, the straight-forward solution is to move it into a separate container of some kind,e.g. a Memory dataset.</p>\n\n<p>4) You need some kind of signaling mechanism to notify main thread once your data retrieval is complete.</p>\n\n<p>...and exception handling isn't straightforward, either...</p>\n\n<p>But: Once you've succeeded, the application will be really elegant !</p>\n"}, {'answer_id': 106960, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>Most TDatasets are not thread safe.  One that I know is thread safe is <a href="http://www.components4programmers.com/products/kbmmemtable/index.htm" rel="nofollow noreferrer" title="kbmMemtable">kbmMemtable</a>.  It also has the ability to clone a dataset so that the problem of moving the record pointer (as explained by Jim McKeeth) does occur.  They\'re  one of the best datasets you can get (bought or free).</p>\n'}]
['https://Stackoverflow.com/questions/78475', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/62/']