Asynchronous Operations in OLE Applications (84982)



The information in this article applies to:

  • Microsoft OLE 1.0

This article was previously published under Q84982

SUMMARY

Under OLE version 1.0, the OLE client and OLE server libraries communicate using dynamic data exchange (DDE) messages. Although this behavior will probably change in the future, the current behavior impacts the application. This article describes the effects of the asynchronous DDE protocol on an OLE application.

MORE INFORMATION

Many OLE function calls, in both the OLE client and OLE server libraries, return the value OLE_WAIT_FOR_RELEASE to signal that the function initiated an asynchronous operation on a specific object, document, or server. While an asynchronous operation is in process, an application must not call any other OLE functions that affect the same item because only one asynchronous operation per item is supported. Therefore, when making a sequence of calls that relate to a single item, the application must wait for each operation to complete before calling the next.

Synchronizing calls in this manner is called "waiting for release" on the item in question. While it waits, an application must continue to process and dispatch messages to exchange DDE messages between the OLE client and OLE server libraries. The application must enter a special message loop to perform this processing and to repeatedly check a flag that indicates that the asynchronous operation is complete.

An OLE server application must determine when the Release method in OLEOBJECTVTBL, OLESERVERVTBL, or OLESERVERDOCVTBL is called. When an OLE function returns OLE_WAIT_FOR_RELEASE for an operation on one of the three items, the server must enter a message loop and check a flag for each message it processes. For example, the application initially sets the flag to FALSE and when the server calls a Release method, the application resets the flag to TRUE. Once the flag is TRUE, the application exits its message loop because the operation is complete. This loop is the extent of waiting in an OLE server application.

An OLE client can determine when an OLEOBJECT is released by watching for an OLE_RELEASE notification in the CallBack method. When the application receives this notification, it sets a flag that causes the message loop to exit. An OLEOBJECT is the only item in a client application that can be busy.

Waiting for All Objects in an OLE Client Application

Some operations, such as closing a file, in an OLE client application affect all objects in a document at the same time; waiting for each object individually is slow. Instead of waiting for each object in turn, an application can wait for all objects together. Note, however, that when this technique is used it is more difficult for the application to articulate errors for individual objects once the application leaves its message loop. However, for operations such as document close, the individual errors may not make any difference to the application.

To wait for all objects at once, maintain a special counter to count how many objects are released and how many objects are waiting. The counter is affected by the following four sets of events:

  • Before executing any operation on all objects, reset the counter to zero.
  • Increment the counter for each OLE call that returns the OLE_WAIT_FOR_RELEASE value.
  • Decrement the counter for each OLE_RELEASE notification received in the CallBack method.
  • Process and dispatch messages until the counter falls to zero, then terminate the loop.
While an application that waits for all objects at once is somewhat more asynchronous during OLE operations, it can be more difficult to detect and to recover from specific errors. An application that waits for each object individually as soon as any call returns OLE_WAIT_FOR_RELEASE uses OLE as a more synchronous protocol. Waiting for all objects together is an option available to the application that may be advantageous. The application must take precautions to ensure that other OLE operations do not occur between time that the application increments the counter and the time the application waits. If the application does not take precautions, the counter may fall below zero.

The OLE_BUSY Return Code

If the OLE server related to an object is involved in a modal operation or an incomplete asynchronous operation, an OLE function call will return the value OLE_BUSY to indicate that the operation cannot be executed. The application can either wait for the object to be released or terminate the operation. Whenever a function returns an OLE_BUSY value, the OLE client application's CallBack method receives an OLE_QUERY_RETRY_BUSY notification. The value returned from CallBack indicates whether or not to continue the operation in response to the notification. When the application receives this notification, it may be wise to inform the user and to provide an option to wait or to cancel.

Debugging Asynchronous Operations

The process of debugging an application that performs multiple operations on multiple objects can be quite involved. One method to address this complexity is to write the application in two phases. In the first phase of development, the application blocks operations on all OLE objects when any OLE function returns OLE_WAIT_FOR_RELEASE. Although waiting for each object in turn will probably cause the application to run more slowly, the application is much easier to debug. Waiting for each object effectively converts OLE into a synchronous protocol.

Once the application has been debugged successfully at phase one, in phase two, extend the program to operate on several objects asynchronously. Extending the application in this manner will most likely improve its performance.

Modification Type:MajorLast Reviewed:10/27/1999
Keywords:KB84982