Cancelling an asynchronous request

This document describes how to cancel an asynchronous request.

Most asynchronous service providers support a cancel function. This allows an outstanding request to be cancelled before it is complete.

A single thread that is waiting for a single asynchronous request to complete cannot cancel that request because the thread is asleep until it completes. However, when multiple requests are outstanding, the handling of a request completion may involve cancelling some or all of the other outstanding requests.

In all cases, the correct user protocol for cancellation is:

    // only cancel if we know that there is
    // an outstanding request
if (requestIssued)
    {
        // Issue cancel to service provider
    provider.cancel();

        // Wait for it complete (it must complete)
    User::WaitForRequest(requestStatus);

        // Now note that request is no longer outstanding
    requestIssued=EFalse;
    }

Notes

  • A cancel should only be issued from the thread that issued the request.

  • It is convention that cancel functions provided by asynchronous service providers have Cancel somewhere in the name, but need not necessarily be called Cancel().

  • An asynchronous service provider must make certain guarantees about cancellation:

    • it must complete quickly — otherwise, the User::WaitForRequest() above would take a long time to complete, and cause the program to become unresponsive

    • it must not violate the guarantee that each request produces precisely one signal

  • The service provider does not have to guarantee to cancel the actual request: it may already have completed — asynchronously, by definition — by the time the client thread issues the cancel.

  • Although the cancel must return quickly, the service initiated by the request may not have completed. For instance, if data were requested from a network drive, it may not be returned until after the cancel. Because of the cancel, the service provider must discard such data.