VB.Net Dispose/G​​arbage Collector 不释放资源? [英] VB.Net Dispose/Garbage Collector not releasing resources?

查看:14
本文介绍了VB.Net Dispose/G​​arbage Collector 不释放资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里使用 VS 2015...只是做了一个小的测试程序来比较使用任务的异步 webrequest 和我之前使用 HttpWebRequest.BeginGetResponse 的方式之间的性能差异

using VS 2015 here...just made a small testing program to compare the performance difference between an async webrequest using tasks and the way I was doing it before with HttpWebRequest.BeginGetResponse

但关键是我试图通过实现 IDispoable 来处理我用于异步请求的状态对象,但在我的诊断中它显示分配的 RAM 大小保持不变?我的印象是调用 dispose 会释放对象正在使用的资源?这是我正在使用的代码,我也尝试将对象设置为 Nothing.

But the point is I tried to dispose of the state object I was using for the async requests by implementing IDispoable, but in my diagnostics it shows that the allocated RAM size remains the same? I was under the impression that calling dispose would release the resources the object was using? Here is the code I am using, I also tried just setting the object to Nothing.

Imports System.Net

Public Class Form1
    Private sw As New Stopwatch

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim req As HttpWebRequest = HttpWebRequest.Create("http://example.com")
        Dim state As New RequestState
        state.req = req
        req.BeginGetResponse(AddressOf respCallback, state)
    End Sub

    Private Sub respCallback(ar As IAsyncResult)
        Dim state As RequestState = ar.AsyncState
        state.resp = state.req.EndGetResponse(ar)
        state.respStream = state.resp.GetResponseStream
        state.respStream.BeginRead(state.buffer, 0, 1024, AddressOf readCallback, state)
    End Sub

    Private Sub readCallback(ar As IAsyncResult)
        Dim state As RequestState = ar.AsyncState
        Dim read As Integer = state.respStream.EndRead(ar)
        If read > 0 Then
            state.respBody += System.Text.ASCIIEncoding.ASCII.GetString(state.buffer, 0, read)
            state.respStream.BeginRead(state.buffer, 0, 1024, AddressOf readCallback, state)
        Else
            state.respStream.Close()
            MsgBox(state.respBody)
            state.Dispose()
        End If
    End Sub

Public Class RequestState
    Implements IDisposable

    Public req As HttpWebRequest
    Public resp As HttpWebResponse
    Public respStream As IO.Stream
    Public buffer(1024) As Byte
    Public respBody As String

#Region "IDisposable Support"
Protected Overridable Sub Dispose(disposing As Boolean)
    If Not disposedValue Then
        If disposing Then
            ' TODO: dispose managed state (managed objects).
            req = Nothing
            resp.Close()
            resp.Dispose()
            resp = Nothing
            respStream.Close()
            respStream.Dispose()
            respStream = Nothing
            buffer = Nothing
            respBody = Nothing
        End If

        ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
        ' TODO: set large fields to null.
    End If
    disposedValue = True
End Sub

    ' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
    'Protected Overrides Sub Finalize()
    '    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' 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(disposing As Boolean) above.
        Dispose(True)
        ' TODO: uncomment the following line if Finalize() is overridden above.
        ' GC.SuppressFinalize(Me)
    End Sub
#End Region
End Class

推荐答案

简单地实现 IDisposable 不会自动释放内存,这取决于程序员释放托管和非托管资源.

Simply implementing IDisposable doesn't automatically free up memory, all that is up to the programmer to release managed and unmanaged resources.

Dispose(disposing As Boolean) 方法中,您必须对每个变量调用 Close()Dispose()实现处置功能:

In the Dispose(disposing As Boolean) method you would have to call Close() or Dispose() on each of your variables that implement the disposing functionality:

Protected Overridable Sub Dispose(disposing As Boolean)
    If Not disposedValue Then
        If disposing Then
            'Here you dispose all managed resources.
            respStream.Close()
            respStream.Dispose()
            resp.Close()
        End If
    End If
    disposedValue = True
End Sub

完成异步操作后,请务必关闭 IAsyncResult.AsyncWaitHandle 对象.您应该能够在每个回调方法的末尾执行此操作:

When you are done with your asynchronous actions, be sure to close the IAsyncResult.AsyncWaitHandle object. You should be able to do this in the end of every callback method:

ar.Close()

这篇关于VB.Net Dispose/G​​arbage Collector 不释放资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆