快速总结:VS 2010 VB.NET 中的应用程序,当前在 Win 2008 服务器上运行以进行测试。它是一个多线程(8 个线程)应用程序,从 .NET 套接字读取数据。
细节:
Public Class StateObject
Public workSocket As Socket = Nothing ' Client socket.
Public BufferSize As Integer = 20000 ' Size of receive buffer. Orig: 20000
Public buffer(20000) As Byte ' Receive buffer. Orig: (20000)
Public sb As New StringBuilder() ' Received data string.
End Class 'StateObject
Private Sub Read_Callback(ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim bytesRead As Long = 0
Dim client As Socket = state.workSocket
SyncLock state
Try
' Read data from the remote device.
bytesRead = client.EndReceive(ar)
If bytesRead > 0 Then ' There might be more data, so store the data received so far.
SyncLock state.sb
**state.sb.Append(Encoding.Default.GetString(state.buffer, 0, bytesRead))**
End SyncLock
If state.sb.Length > 1 Then
SyncLock state.sb
response = state.sb.ToString()
**state.sb.Clear()**
End SyncLock
End If
client.BeginReceive(state.buffer, 0, state.BufferSize, 0, _
AddressOf Read_Callback, state)
Else ' All the data has arrived; put it in response.
If state.sb.Length > 1 Then
SyncLock state.sb
response = state.sb.ToString()
state.sb.Clear()
End SyncLock
End If
readDone.Set()
End If
Catch e As Exception
AppEventLog.WriteEntry("SocketManager.Read_Callback: (LineNum=" & Err.Erl.ToString & ") " & e.Message & vbCrLf & _
"bytesRead = " & bytesRead.ToString & vbCrLf & _
"state.sb.Length = " & state.sb.Length.ToString & vbCrLf & _
"state.sb.Capacity = " & state.sb.Capacity.ToString & vbCrLf & _
"state.sb.MaxCapacity = " & state.sb.MaxCapacity.ToString & vbCrLf & _
"state.workSocket.Available = " & state.workSocket.Available.ToString(), EventLogEntryType.Error)
End Try
End SyncLock
state = Nothing
End Sub 'Read_Callback
这是 Windows 事件视图中的错误日志:
SocketManager.Read_Callback: (LineNum=80) Exception of type 'System.OutOfMemoryException' was thrown.
bytesRead = 20000
state.sb.Length = 0
state.sb.Capacity = 20000
state.sb.MaxCapacity = 2147483647
state.workSocket.Available = 0
**LineNum = 80 causes most errors but sometime occurs at LineNum = 130** (see highlighted lines above)
问题:
- 这是由 StringBuilder 引起的还是其他原因?
- 解决办法是什么?