2016-07-15 28 views
0

使用VS 2015年在這裏......只是做了一個小測試程序,以比較異步之間的性能差異的WebRequest使用任務和方式,我用HttpWebRequest.BeginGetResponseVB.Net Dispose /垃圾收集器不釋放資源?

之前這樣做,但關鍵是我想處置通過實現IDispoable用於異步請求的狀態對象的狀態,但在診斷中顯示分配的RAM大小保持不變?我的印象是調用dispose會釋放對象正在使用的資源?這裏是我使用的代碼,我也嘗試將對象設置爲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 
+1

運行CA對您的應用程序,它會做指出這樣的事情你不實際部署的是'respStream' – Plutonix

+0

的一份體面的工作(重新刪除評論)'Sub Dispose(布爾)'沒有代碼來處理任何東西。另外,RAM與資源不一樣。通過顯示USER和GDI對象列,您有時可以在任務管理器中看到句柄和此類泄漏。 – Plutonix

+0

我對異步編程瞭解不多,但我相信也有一些對象可以在那裏處理。 –

回答

1

簡單地實現IDisposable自動釋放內存,所有這一切都是由程序員來釋放託管和非託管資源。

Dispose(disposing As Boolean)方法,你將不得不呼籲每個變量落實處置功能Close()Dispose()

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對象。你應該能夠做到這一點在每個回調方法的末尾:

ar.Close() 
+0

嗨,我將RequestState對象字段設置爲Nothing,並在IDisposable的Protected Overridable Sub Dispose(disposing As Boolean)方法的實現中的HttpWebRequest和HttpWebResponse字段上調用Dispose,但仍然看不到釋放資源。我可能做錯了:P –

+0

我用Dispose的新實現更新了我的問題。當我啓動應用程序時,基準RAM使用量爲20mb,當我點擊按鈕1併發送請求時,它會上升到22mb,並且儘管我嘗試釋放2mb,但從未回落到基線。 –

+0

@DavidStampher:垃圾收集器可能還沒有運行?它的目的是收集任何未被引用(或處置)的對象。它不會立即運行,你知道。 –