Shutting Down Service Hosts


How should I shut down a running service host?

Here’s a variety of attempts at answering the same question, with varying levels of sophistication thrown into the mix.

Way Too Simple

  • Always call abort, it’s guaranteed to shut things down.

This is the equivalent of shutting your computer down every day by pulling the plug out. It does what it promises but there’s considerable damage as a side-effect.

Bit Too Simple

  • Call abort if the service host has failed.
  • Call close if the service host is running.

The second attempt alleviates some of the collateral damage but has flaws of its own. If the close fails, then we have no way to fall into the error case.

Simple

  • Run your code inside of a catch block.
  • Call close inside the block on the service host.
  • Call abort if an error occurs inside the block.


Advanced

  • Run your code inside of a catch block.
  • Filter out the exceptions from the service host that are recoverable and use them as a signal to restart the host.
  • Call abort if an error occurs inside the block.
  • If the error is recoverable, then start a new service host afterwards.
  • Run your code inside of another catch block.
  • Call close inside the block on the service host
  • Call abort if an error occurs inside the block.

Next time: Detecting Metadata

Comments (5)

  1. How do I measure how busy a service is and how much work is queued up for later processing? There’s no

  2. dominick says:

    cool – so where’s the code?

  3. Nicholas Allen says:

    On open the code looks like this:

    bool openSuccess = false;

    bool regenerateHost = false;

    try

    {

     host.Open();

     openSuccess = true;

    }

    catch (CommunicationException)

    {

     regenerateHost = true;

    }

    catch (TimeoutException)

    {

     regenerateHost = true;

    }

    finally  // don’t break first-pass exception handling

    {

     if (!openSuccess)

     {

         host.Abort();

     }

    }

    if (regenerateHost)

    {

     // put recovery logic here

    }

    While the service is running, recovery is done through an IErrorHandler as described by the post here: http://blogs.msdn.com/drnick/archive/2007/08/21/faking-poison-message-handling.aspx.

    On close the code looks like this:

    bool closeSuccess = false;

    try

    {

     host.Close();

     closeSuccess = true;

    }

    catch (CommunicationException)

    {

    }

    catch (TimeoutException)

    {

    }

    finally  // don’t break first-pass exception handling

    {

     if (!closeSuccess)

     {

         host.Abort();

     }

    }

    // do other post-Close app work here

  4. Julian says:

    Do I really need the openSuccess and closeSuccess flags or can I test the State? (If so, what State should I be testing against?)

  5. Nicholas Allen says:

    It’s a style thing.  In some cases using communication objects, you can have the operation fail without changing the state (such as send or receive on a datagram channel).