4

I'm a little confused about the best way to clean up a ServiceHost. I became aware of the issue in my code because of the CA1001 warning from the Visual Studio code analyzer suggesting I implement the IDisposable interface for my class.

I have read the discussions on IDisposable and am familiar with the typical use case, but find myself confused in this instance. What is the proper way to make sure that the ServiceHost is being disposed and possibly satisfy CA1001. Thanks.

My code looks something like the following:

public class MyClass
{
    private ServiceHost host = null;

    public void StartListening(...)
    {
        // make sure we are not already listening for connections
        if (host != null && host.State != CommunicationState.Closed)
            StopListening();

        // create service host instance
        host = new ServiceHostWithData(typeof(ServiceHandler), address);

        // do a bunch of configuration stuff on the host

        host.Open();
    }

    public void StopListening()
    {
        // if we are not closed
        if ((host != null) && (host.State != CommunicationState.Closed))
        {
            host.Close();
            host = null;
        }
        else // we are null or closed
        {
            host = null; // if it isn't null, and it is already closed, then we set it to null
        }
    }
}

Dhawalk
  • 1,257
  • 13
  • 28
denver
  • 2,863
  • 2
  • 31
  • 45
  • I wrote up a dummy host, and did what you r edoing. I didnt get the warning. Is the warning pointing to this class? – Dhawalk Mar 26 '13 at 16:53
  • 1
    You can use Using (ServiceHost) as msdn example does in their examples – ilansch Mar 26 '13 at 20:01
  • @Dhawalk Yes. The Visual Studio code analyzer is very specific. You might be getting confused with compiler warnings, and in this case there are none. – denver Mar 27 '13 at 04:44
  • @ilansch How does a using block help in this case? He clearly wants the host to be left open once control leaves the StartListening(...) method. – TheNextman Mar 27 '13 at 12:31

1 Answers1

5

Your class should implement IDisposable. Based on the example from that MSDN page:

public class MyClass : IDisposable
{
    private bool disposed = false;
    private ServiceHost host = null;

    public void StartListening(...)
    {
        // ....
    }

    public void StopListening()
    {
        // ...
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    { 
        if(!this.disposed)
        {
            if(disposing)
            {
                this.StopListening();
            }

            disposed = true;
        }
    }

    ~MyClass()
    {
        Dispose(false);
    }
}
TheNextman
  • 12,428
  • 2
  • 36
  • 75
  • Thanks. In terms of the ServerHost is calling ServerHost.Close equivalent to calling ServerHost.Dispose in the MyClass Dispose function? – denver Mar 27 '13 at 04:42
  • 2
    Close and Dispose are essentially the same (see the answer here: http://stackoverflow.com/questions/4964161/wcf-how-to-stop-myservicehost-close-from-disposing-of-myservicehost-object), so you can use either. Be aware that close/dispose on ServiceHost can throw an exception(!), so you might want to try/catch that block, particularly if you are doing other work in the MyClass Dispose function. – TheNextman Mar 27 '13 at 12:30