MultiRead Sample: Reads Database Table Using Multiple Threads

The MultiRead sample demonstrates how to use the OLE DB Consumer Templates classes to read through a table in a database using multiple threads.

The MultiRead attributes sample is the attributed version of this sample.

Security noteSecurity Note

This sample code is intended to illustrate a concept, and it shows only the code that is relevant to that concept. It may not meet the security requirements for a specific environment, and it should not be used exactly as shown. We recommend that you add security and error-handling code to make your projects more secure and robust. Microsoft provides this sample code "AS IS" with no warranties.

To get samples and instructions for installing them:

To access samples from Visual Studio

  • On the Help menu, click Samples.

    By default, these samples are installed in drive:\Program Files\Microsoft Visual Studio 10.0\Samples\.

  • For the most recent version of this sample and a list of other samples, see Visual Studio Samples on the MSDN Web site.

Building and Running the Sample

To build and run this sample

  1. Open the solution file MultiRead.sln.

  2. From the Build menu, click Build.

  3. From the Debug menu, click Start Without Debugging.

  4. A Multi-Threaded Read dialog box will appear, prompting you to specify the number of threads to use to read through the table. Click Run.

  5. The result will appear as text in the Multi-Threaded Read dialog box, for example, 15 records in 7 ms.

How the Sample Works

The sample contains the CMultiDlg class, which is used to show a dialog box. With this dialog box, the user enters the number of threads to use to read through the table. When the user clicks the Run button, ReadRecords in DBRead.h is called to open the database, the session, and the table, and to create the necessary number of threads. As it opens the table, the function sets the DBPROP_CANHOLDROWS property to true so that the provider allows the user to retrieve new rows without releasing the previously retrieved rows. This capability is required, because multiple threads retrieve new rows as other threads are still processing their current threads.

The sample also shows how to extend the standard CRowset class by creating a new CMyRowset class, which derives from CRowset, and adds the MoveAndProcess member function. The start routine of each thread is the ReadTable function, and the table class is passed to this function. The function calls the routine MoveAndProcess to read through each record. Note that the accessor class CProduct is defined so that the data will not be retrieved automatically on the MoveNext call. This avoids buffer conflicts with the other threads, and there is no need to protect MoveNext with a critical section. The MoveAndProcess function calls MoveNext, and then calls GetDataHere to place the data directly into a local variable of that function. ProcessRecord is called for each record retrieved, and the function simply traces out the values of the record by default.

Each thread counts the number of records it reads, and those are traced out at the end, along with a total and time taken, which is displayed on the dialog box.


The MultiRead sample reads the MultiRead.mdb database file. The sample code assumes that this file is located in the current directory.


The sample demonstrates the following classes:

CAccessor, CDataSource, CDBPropSet, CRowset, CSession, CTable

The sample demonstrates the following macros:


The sample demonstrates the following functions:

CreateThread, GetCurrentThreadId, GetExitCodeThread, WaitForMultipleObjects


Some of the samples, such as this one, have not been modified to reflect the changes in the Visual C++ wizards, libraries, and compiler, but still demonstrate how to complete your desired task.

See Also

Other Resources

ATL Samples