Question

Im un débutant complet aux « meilleures pratiques » etc de l'écriture dans un code. J'ai tendance à écrire juste un si ça marche, pourquoi le réparer.

Eh bien, cette façon de travailler me atterrissage dans l'eau chaude. Je suis en train d'écrire un service Windows simples au serveur une seule page Web. (Ce service sera incor- porée dans un autre projet qui surveille les services et certains dossiers sur un groupe de serveurs.)

Mon problème est que chaque fois qu'une demande est reçu, l'utilisation de la mémoire saute par quelques K par demande et maintient qoing sur chaque demande.

Ive a trouvé que, en mettant GC.Collect dans le mélanger arrête à un certain nombre, mais je suis sûr que ce ne est pas destiné à être utilisé de cette façon. Je me demandais si je manque quelque chose ou ne pas faire quelque chose que je devrait libérer de la mémoire.

Voici le code:

Public Class SimpleWebService : Inherits ServiceBase
    'Set the values for the different event log types.
    Public Const EVENT_ERROR As Integer = 1
    Public Const EVENT_WARNING As Integer = 2
    Public Const EVENT_INFORMATION As Integer = 4
    Public listenerThread As Thread
    Dim HTTPListner As HttpListener
    Dim blnKeepAlive As Boolean = True

    Shared Sub Main()
        Dim ServicesToRun As ServiceBase()
        ServicesToRun = New ServiceBase() {New SimpleWebService()}
        ServiceBase.Run(ServicesToRun)
    End Sub

    Protected Overrides Sub OnStart(ByVal args As String())
        If Not HttpListener.IsSupported Then
            CreateEventLogEntry("Windows XP SP2, Server 2003, or higher is required to " & "use the HttpListener class.")
            Me.Stop()
        End If
        Try
            listenerThread = New Thread(AddressOf ListenForConnections)
            listenerThread.Start()
        Catch ex As Exception
            CreateEventLogEntry(ex.Message)
        End Try
    End Sub

    Protected Overrides Sub OnStop()
        blnKeepAlive = False
    End Sub

    Private Sub CreateEventLogEntry(ByRef strEventContent As String)
        Dim sSource As String
        Dim sLog As String
        sSource = "Service1"
        sLog = "Application"
        If Not EventLog.SourceExists(sSource) Then
            EventLog.CreateEventSource(sSource, sLog)
        End If
        Dim ELog As New EventLog(sLog, ".", sSource)
        ELog.WriteEntry(strEventContent)
    End Sub

    Public Sub ListenForConnections()
        HTTPListner = New HttpListener
        HTTPListner.Prefixes.Add("http://*:1986/")
        HTTPListner.Start()
        Do While blnKeepAlive
            Dim ctx As HttpListenerContext = HTTPListner.GetContext()
            Dim HandlerThread As Thread = New Thread(AddressOf ProcessRequest)
            HandlerThread.Start(ctx)
            HandlerThread = Nothing
        Loop
        HTTPListner.Stop()
    End Sub

    Private Sub ProcessRequest(ByVal ctx As HttpListenerContext)
        Dim sb As StringBuilder = New StringBuilder
        sb.Append("<html><body><h1>Test My Service</h1>")
        sb.Append("</body></html>")
        Dim buffer() As Byte = Encoding.UTF8.GetBytes(sb.ToString)
        ctx.Response.ContentLength64 = buffer.Length
        ctx.Response.OutputStream.Write(buffer, 0, buffer.Length)
        ctx.Response.OutputStream.Close()
        ctx.Response.Close()
        sb = Nothing
        buffer = Nothing
        ctx = Nothing
        'This line seems to keep the mem leak down
        'System.GC.Collect()
    End Sub
End Class

S'il vous plaît ne hésitez pas à critisise et déchirer le code en dehors, mais s'il vous plaît BE NATURE QUE CE SOIT. Je l'ai admis je ne tends à suivre les meilleures pratiques en matière de codage.

Était-ce utile?

La solution

Vous avez raison, vous devez pas faire cela. Supprimez l'appel Collect () et le laisser tourner pendant une semaine. Tout livre .NET décent parlera sur le fonctionnement du collecteur d'ordures et comment il le pas libérer immédiatement la mémoire lorsque vous définissez un objet à rien. Il ne démarre pas avant que vous avez consommé quelque part entre 2 et 8 méga-octets. Ce n'est pas une fuite, mais simplement une utilisation efficace d'une ressource abondante.

Vous utilisez un nouveau thread pour chaque connexion individuelle, qui est assez cher et échelles très mal quand vous obtenez beaucoup de connexions. Pensez à utiliser à la place ThreadPool.QueueUserWorkItem. ThreadPool fils sont très pas cher et leur allocation et l'exécution est bien contrôlé par le gestionnaire de threadpool.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top