Microsoft KB Archive/236848

From BetaArchive Wiki

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:

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

Filename Description
Fastread.mdb This is the database file where the records will be written to and read from.
Fastread.dsw This is the overall workspace that contains the reader and writer application projects.
Readerdlg.cpp This file contains the code that demonstrates the use of IIdle and reading the data.
Writerdlg.cpp This file contains the code that writes the records to the database using explicit transactions.


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<CReaderDlg *> (pParam);
    CComQIPtr<IIdle> 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.

REFERENCES

For additional information149618, click the article numberPageTimeout Defaults to Five Seconds in Jet 3.0 below to view the articlePageTimeout Defaults to Five Seconds in Jet 3.0 in the Microsoft Knowledge Base:

%3 %4


%1 %2



Additional query words: pagetimeout FastRead caching read-ahead cursor preservation synchronize

Keywords: kbdownload kbconsumer kbdatabase kbfile kbjet kbsample KB236848