C# 为什么我的服务器';运行一段时间后,s的性能会受到影响吗?

C# 为什么我的服务器';运行一段时间后,s的性能会受到影响吗?,c#,multithreading,asynchronous,server,asyncsocket,C#,Multithreading,Asynchronous,Server,Asyncsocket,我已经编写了服务器代码,它使用多线程(异步)从多个客户端(超过500个)连续接收来自服务器的数据。 它从所有客户端读取数据,并在多线程方面正常工作,并接收客户端发送的所有消息 有什么问题吗? 问题是,当我在1到2小时后继续从客户端读取数据时,我的服务器就会变慢。我的意思是,它不断增加CPU使用率(可能是因为解除了内存冻结…因为这里我们把所有东西都放在垃圾收集器上)。当我看到CPU内存在一段时间后从14%突然上升到80-100%。但它仍然从客户机接收数据(但有一些数据泄漏),但它仍然接收数据。我无

我已经编写了服务器代码,它使用多线程(异步)从多个客户端(超过500个)连续接收来自服务器的数据。 它从所有客户端读取数据,并在多线程方面正常工作,并接收客户端发送的所有消息

有什么问题吗?

问题是,当我在1到2小时后继续从客户端读取数据时,我的服务器就会变慢。我的意思是,它不断增加CPU使用率(可能是因为解除了内存冻结…因为这里我们把所有东西都放在垃圾收集器上)。当我看到CPU内存在一段时间后从14%突然上升到80-100%。但它仍然从客户机接收数据(但有一些数据泄漏),但它仍然接收数据。我无法确定问题的原因

有人能告诉我是什么原因引起的吗

代码的重要部分是:

public void StartServer() 
{
    try 
    {
        server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
        server.Bind(ipep);
        server.Listen(4);
        AppendIncomingData(txtMsg, "Server Started..");

        btnStart.Enabled = false;
        lblStartDate.Text = DateTime.Now.ToString();
        server.BeginAccept(new AsyncCallback(AcceptConn), server);
    } 
    catch (Exception ex) 
    {
        AppendIncomingData(txtError, ex.Message);
    }
}

void AcceptConn(IAsyncResult ia)
{
    Socket client;
    try
    {
        Socket oldserver = (Socket) ia.AsyncState;
        client = oldserver.EndAccept(ia);

        StateObject state = new StateObject();
        state.workSocket = client;
        client.ReceiveTimeout = 1000;
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
        server.BeginAccept(new AsyncCallback(AcceptConn), server);
    }
    catch (Exception ex) 
    {
        AppendIncomingData(txtError, "AcceptConn Exception : " + ex.Message);
    }
}

/// <summary>
/// StateObject Class to read data from Client
/// </summary>
public class StateObject
{
    // Client  socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 512;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
    public Int64 DeviceId = 0;
}

void ReceiveData(IAsyncResult ia)
{
    StateObject state = (StateObject)ia.AsyncState;
    Socket client = state.workSocket;

    string sql = "";
    string stringData = "";
    try
    {
        recv = client.EndReceive(ia);
        if (recv == 0)
        {
            client.Close();
            server.BeginAccept(new AsyncCallback(AcceptConn), server);
            return;
        }

        Array.Resize(ref state.buffer, StateObject.BufferSize);
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
    } //End Try
    catch (Exception ex)
    {
        AppendIncomingData(txtError, "ReceiveData Error : " + stringData + ": " + ex.Message);

        client.Close();
        server.BeginAccept(new AsyncCallback(AcceptConn), server);
    }
}

public void AppendIncomingData(object dataControl, string str)
{
    if (btnMsg.Text.ToUpper().Contains("START") == true)
        return;

    TextBox lst = (TextBox)dataControl;

    if (lst.InvokeRequired)
    {
        AppendIncomingData_Delegate method = new AppendIncomingData_Delegate(AppendIncomingData);
        lst.Invoke(method, new object[] { lst, str });
    }
    else
    {
        msglines += 1;
        if (msglines > 500)
        {
            msglines = 0;
            //lst.Clear();
            txtError.Clear();
            txtMsg.Clear();
        }
        lst.AppendText(Environment.NewLine + DateTime.Now.ToString() + " " + str);
    }
}
public void StartServer()
{
尝试
{
服务器=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
IPEndPoint ipep=新IPEndPoint(IPAddress.Any,端口);
服务器绑定(ipep);
服务器。听(4);
AppendIncomingData(txtmg,“服务器已启动…”);
btnStart.Enabled=false;
lblStartDate.Text=DateTime.Now.ToString();
beginacept(新的异步回调(AcceptConn),server);
} 
捕获(例外情况除外)
{
附录输入数据(TXError,例如消息);
}
}
无效接受连接(IAsyncResult ia)
{
套接字客户端;
尝试
{
Socket oldserver=(Socket)ia.AsyncState;
client=oldserver.EndAccept(ia);
StateObject状态=新的StateObject();
state.workSocket=客户端;
client.ReceiveTimeout=1000;
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveData),state);
beginacept(新的异步回调(AcceptConn),server);
}
捕获(例外情况除外)
{
AppendIncomingData(TXError,“AcceptConn异常:”+ex.Message);
}
}
/// 
///用于从客户端读取数据的StateObject类
/// 
公共类状态对象
{
//客户端套接字。
公共套接字工作组=null;
//接收缓冲区的大小。
public const int BufferSize=512;
//接收缓冲区。
公共字节[]缓冲区=新字节[BufferSize];
//接收到的数据字符串。
公共StringBuilder sb=新StringBuilder();
公共Int64设备ID=0;
}
无效接收数据(IAsyncResult ia)
{
StateObject状态=(StateObject)ia.AsyncState;
套接字客户端=state.workSocket;
字符串sql=“”;
字符串stringData=“”;
尝试
{
recv=client.EndReceive(ia);
如果(recv==0)
{
client.Close();
beginacept(新的异步回调(AcceptConn),server);
返回;
}
Resize(ref state.buffer、StateObject.BufferSize);
client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReceiveData),state);
}//结束尝试
捕获(例外情况除外)
{
AppendIncomingData(TXError,“ReceiveData错误:“+stringData+”:“+ex.Message”);
client.Close();
beginacept(新的异步回调(AcceptConn),server);
}
}
public void AppendIncomingData(对象数据控件,字符串str)
{
if(btnMsg.Text.ToUpper().包含(“开始”)==true)
返回;
TextBox lst=(TextBox)数据控件;
如果(需要第一次调用)
{
AppendIncomingData_委托方法=新的AppendIncomingData_委托(AppendIncomingData);
Invoke(方法,新对象[]{lst,str});
}
其他的
{
msglines+=1;
如果(msglines>500)
{
msglines=0;
//lst.Clear();
txtError.Clear();
txtMsg.Clear();
}
lst.AppendText(Environment.NewLine+DateTime.Now.ToString()+“”+str);
}
}

可能是什么问题?

您描述的症状是内存使用量单调增加。也就是说,随着时间的推移,您的程序会分配越来越多的内存。最终,分配了如此多的内存,以至于其中一些必须交换到磁盘。但是,如果所有分配的内存仍在正常使用,则必须将该内存换回RAM,并将其他内存换出。这被称为“鞭打”

如果不能可靠地证明问题,就不可能确切地知道问题是什么。但代码中有几个明显的问题可能是原因:

  • 关闭连接时调用
    beginacept()
    ,并且在打开连接时调用它。这意味着随着时间的推移,您将创建越来越多的未完成的接受I/O操作
  • 上述问题可能相对较小,但如果不确定客户行为模式,就不可能确定。由于这个问题的几何性质,随着时间的推移,它很容易向进程添加大量内存分配

    还有这个

  • 您似乎在维护一个
    文本框
    控件,在其中添加与服务器操作相关的状态消息(例如异常和客户端连接通知)。您已经注释掉了将清除相关
    文本框的行。当您清除
    txtError
    txtMsg
    对象时,值得注意的是,您的接收完成回调方法对接收到的数据没有任何作用,这表明您出于某种原因在代码示例中忽略了该细节。因此,当您收到数据时,您也可能正在向其他
    文本框
    写入数据,而没有清除该文本框
  • 还有一种可能性是,您没有放弃关闭套接字的
    状态
    对象。同样,你发布的代码没有任何作用
    void AcceptConn(IAsyncResult ia)
    {
        Socket client;
        try
        {
            Socket oldserver = (Socket) ia.AsyncState;
            client = oldserver.EndAccept(ia);
    
            StateObject state = new StateObject();
            state.workSocket = client;
            client.ReceiveTimeout = 1000;
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveData), state);
            server.BeginAccept(new AsyncCallback(AcceptConn), server);
        }
        catch (Exception ex) 
        {
            AppendIncomingData(txtError, "AcceptConn Exception : " + ex.Message);
        }
    }