Microsoft KB Archive/236848

= SAMPLE: Fastread Demonstrates the Use of the OLE DB Provider for Jet IIdle Interface =

Article ID: 236848

Article Last Modified on 8/5/2004

-

APPLIES TO


 * Microsoft OLE DB Provider for Jet 3.51
 * Microsoft OLE DB Provider for Jet 4.0
 * Microsoft Visual C++ 6.0 Enterprise Edition
 * Microsoft Visual C++ 6.0 Professional Edition
 * Microsoft Visual C++ 6.0 Standard Edition

-



This article was previously published under Q236848



SUMMARY
Fastread.exe is a sample that demonstrates the use of the IIdle interface exposed by the OLE DB Provider for Jet. Using the IIdle interface, an application can refresh the Jet cache with the latest values from a database. This is important in the case where one application writes to the database and another application needs to get that data immediately.

The Fastread sample consists of a single workspace with two projects. One application is the writing application, and it will update the Access table with a new record every 0.5 seconds. The other project is the reading application, which will receive an event from the writer telling it that the data has been written. To guarantee that the data will be written, the writing application performs a transaction. To guarantee that the reading application can see the new data after receiving the event to read the new data from the writer, the reading application calls IIdle->Idle(0) to refresh the internal Jet cache with the latest values.

The reading application brings up a dialog box that contains a checkbox for using IIdle. If you click the button to begin reading and do not have the Use IIdle checkbox selected, you will get a number of duplicate records in the list control. This is caused by the reader application reading the same record repeatedly from the local Jet cache rather than Jet continuously retrieving the values from the database file. When Use IIdle is selected, you will see only unique records that the writing application is sending.

To use the sample, first build both projects. Run the reader first and click the button to begin reading, and then execute the writer and click the button to begin sending records. At any time you can click the buttons to stop the reading or the writing.



MORE INFORMATION
The following file is available for download from the Microsoft Download Center:

FastRead.exe

Release Date: September 8, 2000

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

Main Files in the Self-extracting EXE
The core code that demonstrates the reading of the data is in the Readerdlg.cpp file, which is contained in the Reader subfolder. Here is the function for the reading thread: UINT ReaderThreadFunc( LPVOID pParam ) {   HRESULT hr; CGUIDTableRS rs; CReaderDlg * pDlg = reinterpret_cast (pParam); CComQIPtr spIdle;

CoInitialize(NULL);

CEvent WriteEvent(FALSE, FALSE, "FastReadWriteEvent"); CEvent ReadEvent(FALSE, FALSE, "FastReadReadEvent"); CSingleLock lck(&ReadEvent);

// open up the table hr = rs.Open; spIdle = rs.m_session.m_spOpenRowset;

// signal writer that we are ready to receive WriteEvent.SetEvent; // loop until stop button is pressed or application is exited while (!gbStopReading) {       // if event for sending next record signaled if (lck.Lock(1000)) {           // for every lock there must be an unlock or you will get an assert lck.Unlock;

// clear ReadEvent - writer app will set the event the next time // a record is ready. ReadEvent.ResetEvent;

if (pDlg->m_bUseIIdle) spIdle->Idle(0);

// reader told us to go ahead and write record if (FAILED(ReadRecord(rs, pDlg))) {               AfxMessageBox("Failure writing record. The application will stop send records."); gbStopReading = true; }           else {               // signal writer that we are ready to receive another record WriteEvent.SetEvent; }

}   }

rs.Close; return 0; }

The documentation for the IIdle interface does not explain what the valid parameter values are for IIdle. You can use a value of 0.

The important element of the writing application is that explicit transactions are used to ensure that the data is written to the database file. To do this, first DBPROP_COMMITPRESERVE should be set to true for the rowset so that a requery of the rowset is not necessary after each commit. In the GUIDTableRS.H file you will see: propset.AddProperty(DBPROP_COMMITPRESERVE, true);

Secondly, in the writing thread function, you will see the following code:

hr = rs.m_session.StartTransaction; // reader told us to go ahead and write record // first a delay to help with the demo so that a bunch of records aren't being // rapidly fired off so that the reader doesn't get a chance to display anything Sleep(500);

if (FAILED(WriteRecord(rs))) {     AfxMessageBox("Failure writing record. The application will stop send records."); gbStopSending = true; rs.m_session.Abort; }  else {     hr = rs.m_session.Commit; // signal reading app that we sent a record and it is ready to read ReadEvent.SetEvent; }

Notice the use of the StartTransaction and Commit functions of the session object.

