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;
}
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.