This documentation is archived and is not being maintained.

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 provided to illustrate a concept and should not be used in applications or Web sites, as it may not illustrate the safest coding practices. Microsoft assumes no liability for incidental or consequential damages should the sample code be used for purposes other than as intended.

To get samples and instructions for installing them:

  • On the Visual Studio Help menu, click Samples.

    For more information, see Visual Studio Samples.

  • The most recent version and complete list of samples is available online from the Visual Studio 2008 Samples page.

  • You can also locate samples on your computer's hard disk. By default, samples and a Readme file are copied into a folder under \Program Files\Visual Studio 9.0\Samples\. For Express editions of Visual Studio, all samples are located online.

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.

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.

Other Resources