Are Windows Runtime asynchronous operations guaranteed to complete?

Raymond Chen

Raymond

The Windows Runtime uses asynchronous operations, which are operations which start and return immediately, and then notify you when the operation has completed. This lets you do other things while waiting for the operation. Most programming languages nowadays have built-in support for this style of programming, usually by using some variation of the keyword await.

Is there any guarantee that a Windows Runtime operation will eventually complete?

Is there any guarantee that any operation will eventually complete?

Not really.

For example, you might display a dialog box to the user by calling MessageBox.ShowAsync. This completes when the user responds to the dialog. But what if the user isn’t there? The dialog box remains on screen indefinitely. Now, it’s possible that the user might return someday, so you might argue that the operation hasn’t definitely gotten stuck, because the user can always unstick it by responding to the dialog box.

The AnimatedVisualPlayer.PlayAsync method completes when the animation stops. This happens naturally if you ask the animation to play to the end and stop, but if you ask for a looping animation, then it doesn’t stop until you manually call Stop to stop it. Does this mean that there’s no guarantee that the PlayAsync will ever complete? I mean, your program can always unstick it by calling Stop.

Each asynchronous operation defines the conditions under which it will complete. If those conditions are never met, then it will never complete. There’s nothing special about asynchronous operations here. This can happen with synchronous functions, too. If you ask Wait­For­Single­Object to wait for a handle that will never be signaled, then it will never return.

Bonus chatter: You can easily create your own Windows Runtime asynchronous operation that never completes.

winrt::IAsyncAction HangAsync()
{
    co_await std::experimental::suspend_always{};
}

The suspend_always object suspends and never wakes up. Awaiting it will never complete. And that means that the IAsyncAction you created from it will never complete.

 

8 comments

Comments are closed.

  • Avatar
    Dmitry Vozzhaev

    What if something extraordinary happens, like a network driver has crashed while I was downloading a file. Is some outcome of the operation guaranteed, or it’s completion is a best effort and in unlucky circumstances operation might stuck indefinitely without anything material left to wait for?

    • Raymond Chen
      Raymond ChenMicrosoft logo

      If a network driver initiates a read request and never completes it, then that’s going to make all the higher layers wait indefinitely for the result of the I/O operation. I would argue that that’s a bug in the network driver. There’s nothing particularly special about asynchronous operations here. A synchronous ReadFile would suffer the same fate.

      • Avatar
        Piotr Siódmak

        With network stuff, never completing is a given – you should assume it might happen, since it involves parts that are out of your and your system’s control. An HD Driver fails to respond? The operating system knows the driver it controls is supposed to respond and has a watchdog keeping it in check (there’s a bluescreen if the system drive doesn’t respond for 2 minutes I think). With network it’s up to you to specify a timeout policy. Maybe you’re listening on a UDP port to see who will report within the next 5 minutes, or maybe you’re waiting for an HTTP response and should give up after 2 minutes.
        The point is that with the file system, the OS can help you since it encapsulates that. At least it should by calling the callback with some parameter specifying cancellation due to timeout (whether the specific implementation actually does that is a different story). With network protocols (above TCP or UDP) you’re on your own, because noone other than you knows anything about it.

        • Raymond Chen
          Raymond ChenMicrosoft logo

          Presumably a read from a network socket will at least complete when the socket connection is lost. That’s all the network stack’s problem. If the network stack says “A call to read from a socket may never complete, ever” well, that’s their decision.

  • Avatar
    James Sutherland

    Deep inside Windows, there are (or at least were at some time) some wait operations which are intended never to complete – after the Session Manager (SMSS.exe) creates the first CSRSS.exe instance, it waits for that instance to exit, which should never happen since it’s a critical process. (As I recall, if it does complete, it triggered a BSOD/BugCheck, but the ‘critical process’ flag has the same effect too: I’d guess this is because that predated the addition of critical process flags?)