Monitoring a WCF Service Host
October 13 2008 2 Comments
One problem I’ve been running into is my ServiceHosts failing out in my long running background services. I’ve written the following class to help monitor the service hosts and restart them if they fail. This is still experimental, and I’m not sure how well it’s going to work, so any feedback would be appreciated.
The delegate is used to recreate the host whenever it needs to be created. Just pass in a delegate to a function that creates the ServiceHost and initializes all of its bindings, etc.
Public Delegate Function ServiceHostCreateDelegate() As ServiceHost Public Class ServiceHostMonitor Implements IDisposable Private _del As ServiceHostCreateDelegate Private WithEvents _host As ServiceHost Public ReadOnly Property Host() As ServiceHost Get If _host Is Nothing Then CreateHost() End If Return _host End Get End Property Public ReadOnly Property HostCreated() As Boolean Get Return _host IsNot Nothing End Get End Property Private _hostName As String Public ReadOnly Property HostName() As String Get Return _hostName End Get End Property Public ReadOnly Property State() As CommunicationState Get Return Host.State End Get End Property Public Sub New(ByVal createDelegate As ServiceHostCreateDelegate, ByVal hostName As String) If createDelegate Is Nothing Then Throw New ArgumentNullException("createDelegate") End If If hostName Is Nothing Then Throw New ArgumentNullException("hostName") End If _del = createDelegate _hostName = hostName End Sub Protected Overrides Sub Finalize() Dispose(False) End Sub Protected Sub CreateHost() If HostCreated Then Close() End If _host = _del.Invoke() End Sub Public Sub Open() Try CreateHost() Host.Open() Logger.LogMessage("Opened Service Host " & _hostName) Catch ex As Exception Logger.LogException(ex, "Error Opening Service Host " & _hostName) End Try End Sub Public Sub Close() Try If HostCreated Then If State = CommunicationState.Opened Then Host.Close() End If _host = Nothing End If Catch ex As Exception Logger.LogException(ex, "Error Closing Service Host " & _hostName) End Try End Sub Private Sub _host_Faulted(ByVal sender As Object, ByVal e As System.EventArgs) Handles _host.Faulted Logger.LogError("Service Host Faulted " & _hostName) Open() End Sub #Region "IDisposable" Private disposedValue As Boolean = False ' To detect redundant calls ' IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then Close() End If ' TODO: free shared unmanaged resources End If Me.disposedValue = True End Sub #Region " IDisposable Support " ' This code added by Visual Basic to correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region #End Region End Class
Please note that the Logger.LogError and Logger.LogMessage calls are for the custom error logging in my application. You should replace this with your own error logging as you see fit.
I don’t think you can just open the channel again after it faulted. You will need to recreate the host.
That is correct, you can’t just reopen the channel. That’s why I’m using a delegate back to recreate the host whenever it needs to be reopened.