c# - 可以更有效地处理这个异步套接字吗

标签 c# performance asynchronous

我收到了大量消息,我想让我的 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/

相关文章:

c# - Azure 网站.well-known 路由变得无法访问

c# - 如何获取经过身份验证的用户名、IP 地址和从 HTTP 过滤器调用的 Controller 操作?

c++ - std::equal_range 的可能实现

node.js - 向异步 waterfall 添加异步函数

c# - 程序关闭时后台工作线程没有关闭?

c# - 有没有办法使用 Microsoft.SharePoint.Client 命名空间与其他用户一起创建新的列表项

javascript - Mongo 脚本在本地运行速度很快,但如果我针对远程实例运行它会很慢?

javascript - 为每个 id 发出请求或按 ids 过滤请求

C# 异步套接字同时读写?

c# - 使用 Async/Await 重写我的 Utils 库的正确方法