我收到了大量消息,我想让我的 ReceivedCallBack 更有效率。
我正在使用一些方便的字符串处理 - 但有更快的方法吗?
public class StateObject
{
public Socket socket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
public string SessionID()
{
return socket.Handle.ToString();
}
}
public void ReceivedCallBack(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
try
{
int bytesRead = socket.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
string[] contents = state.sb.ToString().Split('@');
int delimCount = state.sb.ToString().Count(x => x == '@');
for (int d = 0; d < delimCount; d++)
{
if (contents[d] != "")
OnMessage(state, contents[d]);
}
if (!state.sb.ToString().EndsWith("@"))
{
state.sb.Clear();
state.sb.Append(contents[contents.Count() - 1]);
}
else
{
state.sb.Clear();
}
socket.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceivedCallBack), state);
}
else
{
// If no data was recieved then the connection is probably dead
OutputWriteLine("Client " + state.SessionID() + " disconnected");
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Unusual error during Receive!");
}
}
最佳答案
这里有一个根本性的问题:在处理当前套接字时,套接字没有缓冲区。内核可能丢包,导致重试。对于高吞吐量,您应该发布多个缓冲区并在接收完成后立即重新发布新的空缓冲区,然后再处理已完成的缓冲区。话虽如此, 说,使用多个缓冲区实现正确的处理非常,因为您必须跟踪发布的顺序并且必须小心处理不完整的消息(您不能重新发布消息的“其余”部分填充了缓冲区,因为已经发布了一个缓冲区)。阅读链接在 High Performance Windows programs 的文章了解更多详情。
现在,使用您拥有的代码:分析它。从 Beginners Guide to Performance Profiling 开始.我怀疑您会发现常见的罪魁祸首(例如 string.Split()
中的分配),但我建议您衡量自己,找到瓶颈,然后才进行更改。
对于您的字符串处理,请阅读这个经典:why GNU grep is fast (尽管使用 Boyer-Moore 搜索单个 @
不会产生如此大的影响)。如果可能,请考虑将协议(protocol)更改为更易于解析的协议(protocol)(例如二进制 proto buff )。
关于c# - 可以更有效地处理这个异步套接字吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31533677/