主執行緒持有 SocketWrapper s,兩個子執行緒同時呼叫 s.Send(),未同步可能導致資料交錯、Socket 錯誤。
Private ReadOnly _sendLock As New Object()
Public Sub Send(data As Byte())
SyncLock _sendLock
_socket.Send(data)
End SyncLock
End Sub
Private ReadOnly _sendQueue As New ConcurrentQueue(Of Byte())
Private _senderTask As Task
Public Sub Start()
_senderTask = Task.Run(Sub()
While True
If _sendQueue.TryDequeue(out Dim data) Then
_socket.Send(data)
Else
Thread.Sleep(1) // 避免忙等待
End If
End While
End Sub)
End Sub
Public Sub Send(data As Byte())
_sendQueue.Enqueue(data)
End Sub
| 場景 | 推薦方案 |
|---|---|
| 發送頻率低 (<100/s)、資料小 | 方案一 鎖定 |
| 高頻、大資料、需保證順序 | 方案二 佇列 |
| 需支援取消、背壓控制 | 方案二 + CancellationToken |
Socket.Send 本身非執行緒安全,多執行緒並發呼叫會導致 WSAEINVAL 或資料損壞。_sendQueue.CompleteAdding() 並 _senderTask.Wait()。VB.NET 多執行緒共用 Socket 發送,必須同步。低併發用 SyncLock,高併發用 ConcurrentQueue + 專用發送執行緒,後者擴充性更強。