C# 可以更有效地处理这个异步套接字吗
我收到了大量的信息,我希望我的ReceivedCallBack更高效 我正在使用一些方便的字符串处理-但是有没有更快的方法C# 可以更有效地处理这个异步套接字吗,c#,performance,asynchronous,C#,Performance,Asynchronous,我收到了大量的信息,我希望我的ReceivedCallBack更高效 我正在使用一些方便的字符串处理-但是有没有更快的方法 public class StateObject { public Socket socket = null; public const int BufferSize = 256; public byte[] buffer = new byte[BufferSize]; public Strin
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!");
}
}
公共类StateObject
{
公共套接字=空;
public const int BufferSize=256;
公共字节[]缓冲区=新字节[BufferSize];
公共StringBuilder sb=新StringBuilder();
公共字符串SessionID()
{
返回socket.Handle.ToString();
}
}
收到的公共无效回拨(IAsyncResult ar)
{
StateObject状态=(StateObject)ar.AsyncState;
套接字=state.Socket;
尝试
{
int bytesRead=socket.EndReceive(ar);
如果(字节读取>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='@');
对于(int d=0;d
这里有一个根本性的问题:在处理当前套接字时,将套接字保留在没有缓冲区的情况下。内核可能会丢弃数据包,导致重试。为了获得高吞吐量,您应该在处理完成的缓冲区之前,在接收完成时立即发布多个缓冲区并重新发布新的空缓冲区。话虽如此,使用多个缓冲区实现正确的处理是非常困难的,因为您必须跟踪已发布的订单,并且必须小心处理未完成的消息(您不能为消息的“其余部分”重新发布部分已填充的缓冲区,因为已发布了缓冲区)。有关更多详细信息,请阅读链接至的文章
现在,使用您拥有的代码:配置它。首先。我怀疑您会发现常见的罪魁祸首(例如string.Split()
中的分配),但我建议您测量自己,找到瓶颈,然后再进行更改
对于您的字符串处理,请阅读以下经典内容:(尽管使用搜索单个
@
不会有太大影响)。如果可能的话,考虑将协议更改为更友好的解析(如二进制)。 < P>字符串处理确实非常低效。每个消息的分配、LINQ和二次处理成本。而且,给某人打三次电话也没用
将应用程序置于满载状态,并分析此代码,以查看是否需要对其进行优化。如果是,您可能应该首先应用一些简单的修复程序,并解决我提到的问题
一般来说,您可能不应该编写自己的(基于ASCII的)网络协议。只需使用一些现成的东西,如WCF、HTTP或protobuf。您不需要
delimCount
,只需使用foreach(contents中的字符串内容){if(!string.IsNullOrEmpty(content))OnMessage(state,content);}