I figured this out. This issue is happening because the underlying buffer on the variable m_ClientSendArgs is constantly being changed using SetBuffer:
byte buffer = m_ClientSendQueue.Dequeue(); m_ClientSendArgs.SetBuffer(buffer, 0, buffer.Length);
When I assigned a static buffer to it and used Buffer.BlockCopy, the issue went away:
byte buffer = m_ClientSendQueue.Dequeue(); Buffer.BlockCopy(buffer, 0, m_ClientSendBuffer, 0, buffer.Length); m_ClientSendArgs.SetBuffer(0, buffer.Length);
So I've been implementing it wrong all along. It's strange that it wasn't an issue on .NET 3.5, or an issue for TCP on .NET 4.0/4.5.