MultiRead Attributes Sample: Reads Database Table Using Multiple Threads
The MultiRead attributes sample demonstrates how to use the OLE DB consumer template classes to read through a table in a database using multiple threads.
The MultiRead sample is the nonattributed version of this sample.
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.
Building and Running the Sample
Open the solution file MultiRead.sln.
From the Build menu, click Build.
From the Debug menu, click Start Without Debugging.
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.
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, session, and 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.
This sample uses the following attributes:
db_column, db_source, db_table, exe, helpstring, module, name, threading, uuid, version
The sample demonstrates the following classes:
CAccessor, CDataSource, CDBPropSet, CRowset, CSession, CTable
The sample demonstrates the following macros:
BEGIN_ACCESSOR_MAP, BEGIN_ACCESSOR, COLUMN_ENTRY, END_ACCESSOR, END_ACCESSOR_MAP, DEFINE_COMMAND
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.