私は、いくつかの奇妙なシャットダウン動作が異なるWindowsサービスで、次のクラスを持っています。サーバーは、イベントログのこのメッセージだけで時折シャットダウンし、トレースログには「ブロードキャスターサービスが予期せず終了しました。この1回は完了しました」というメッセージが表示されます。私には際立っているこのクラスのソケットでBeginAcceptを呼び出すタイミング
Public Class ServerSocket
Implements IServerSocket
Public Event ClientConnected(ByVal sender As Object, ByVal e As EventArgs(Of IClientSocket)) Implements IServerSocket.ClientConnected
Private _socket As Socket
Private ReadOnly _settings As IBroadcasterServiceSettingsSection
Private ReadOnly _traceSource As ITraceSource
Public Sub New()
Me.New(BroadcasterServiceSettingsSection.GetSection, BroadcasterTraceSource.Instance)
End Sub
Public Sub New(ByVal settings As IBroadcasterServiceSettingsSection, ByVal traceSource As ITraceSource)
_settings = settings
_traceSource = traceSource
End Sub
Public Sub Listen() Implements IServerSocket.Listen
Dim endPoint As New IPEndPoint(System.Net.IPAddress.Parse(_settings.BroadcasterIPAddress), _settings.BroadcasterPortNumber)
Try
_socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
_socket.Bind(endPoint)
_socket.Listen(SocketOptionName.MaxConnections)
_socket.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), Nothing)
_traceSource.TraceInformation("ServerSocket listening for new clients.")
Catch ex As Exception
_traceSource.TraceCritical("ServerSocket caughtException trying to wait for a new client.")
Throw ex
End Try
End Sub
''' <summary>
''' First attempts to shutdown the socket to clean up any remaining data left to send or receive. Then closes
''' the socket to release all connections and clean up unmanaged resources. See also <seealso cref="System.Net.Sockets.Socket.Shutdown">Socket.Shutdown</seealso>
''' and <seealso cref="System.Net.Sockets.Socket.Close">Socket.Close</seealso>
''' </summary>
Public Sub Close() Implements IServerSocket.Close
Try
_socket.Shutdown(SocketShutdown.Both)
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Error, "Shutting down Server Socket caused an exception.", ex.Message, ex.StackTrace)
End Try
Try
_socket.Close()
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Error, "Closing the Server Socket caused an exception.", ex.Message, ex.StackTrace)
End Try
_traceSource.TraceEvent(TraceEventType.Information, "ServerSocket closed.")
End Sub
Private Sub AcceptCallback(ByVal ar As IAsyncResult)
Dim s As Socket = Nothing
Try
s = _socket.EndAccept(ar)
Catch ex As Exception
_traceSource.TraceInformation("ServerSocket caught exception trying to get new socket for client.", ex.Message, ex.StackTrace)
End Try
Try
' call the begin accept as soon as possible so that I can get the next incoming client
_socket.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), Nothing)
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Critical, "ServerSocket caughtException trying to wait for a new client.", ex.Message, ex.StackTrace)
End Try
Try
If s IsNot Nothing Then
Dim clientSocket As IClientSocket = New ClientSocket(s)
OnClientConnected(New EventArgs(Of IClientSocket)(clientSocket))
End If
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Critical, "9/23 Review: " + ex.ToString())
End Try
End Sub
Private Sub OnClientConnected(ByVal e As EventArgs(Of IClientSocket))
RaiseEvent ClientConnected(Me, e)
End Sub
End Class
一つは、_socket.EndAcceptが_socket.BeginAcceptが呼び出され、その後、「クライアントソケット」との作業が行われていると呼ばれた直後ということです。私はそれに私の指を置くことはできませんが、これはちょうど良い臭いはありません。新しい接続をリッスンするために使用されているソケットは、フィールドとして保持する必要がありますか?そうでない場合は、後でシャットダウンする方法を教えてください。これは非常に長い実行中(週/月)のプロセスです。
各時間の最後に、メモリ使用量をキャプチャします。 –