c# - 晚上 10 点后抛出 System.OutOfMemoryException。我无法捕捉到实际的错误

标签 c# multithreading sockets tcpclient

在服务器上安装了以下软件:

  1. Windows Server 2012、SQL Server
  2. 赛门铁克防病毒软件
  3. 基于Nginx、MS Sql Server DB的指纹识别器

我找不到错误。线程抛出错误 System.Outofmemory 并且服务器有 6GB 可用内存。一个socket接收的最大数据量小于4kb

class ServerModule
{
    TcpListener serverSocket;

    public void StartServer()
    {
        serverSocket.Start();
        while (true)
        {
            try
            {
                if (cmd == -1)
                {
                    break;// stop loop
                }
                Console.WriteLine("Listening");
                TcpClient tc= serverSocket.AcceptTcpClient();
                System.Threading.Thread obj_thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessData));
                obj_thread.Start(tc);
            }
            catch (Exception ex)
            {
                ErrorLogger.LogError("StartServer::", ex);
            }
        }
    }

    public void ProcessData(object ob)
    {
        TcpClient tcp_socket = (TcpClient)ob;
        NetworkStream ns = null;
        try
        {
            ns = tcp_socket.GetStream();
            int num = 0;
            byte[] obj_data = new byte[tcp_socket.ReceiveBufferSize];
            num = ns.Read(obj_data, 0, tcp_socket.ReceiveBufferSize);
            tcp_socket.Close();
            tcp_socket = null;
        }
        catch (Exception ex)
        {
            ErrorLogger.LogError("ProcessData::", data_from_device, ex);
            if (tcp_socket != null)
            {
                tcp_socket.Close();
                tcp_socket = null;
            }
            Console.WriteLine("Close with exception");
        }
    } 
}

最佳答案

您的代码抛出 OutOfMemoryException 因为其中创建了许多线程。看:

// in a infinite loop
while (true)
{
    ...
    // for each TcpClient
    TcpClient tc= serverSocket.AcceptTcpClient();
    // you create a thread!
    System.Threading.Thread obj_thread = new System.Threading.Thread
}

这是您在代码中可以做的最糟糕的事情。由于大量线程同时尝试监听 TcpClients,您的应用程序陷入困境。应用程序中建议的线程数等于服务器计算机上的内核数 ( Managed Threading Best Practices )。

您确实应该使用一些线程池,无论是您自己编写的(我个人不推荐它)还是已经内置的线程池( How to: Use a Thread Pool (C# and Visual Basic) )。

如果您使用的是 .NET 4.5,请使用 Tasks library简化您的代码。
现在您的应用程序不稳定并且容易出错。

如果出于某种原因,您仍然认为每次调用 TcpClient 时都应该创建一个 Thread (我认为这是完全错误的),您应该阅读本手册:

How to: Create and Terminate Threads (C# Programming Guide)

关于c# - 晚上 10 点后抛出 System.OutOfMemoryException。我无法捕捉到实际的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33277484/

相关文章:

c# - 如何在没有中间对象的情况下按字母顺序对两个单独的列表进行排序?

c - 任务比较多的线程池

python - python多线程中thread.join和thread.abort的区别

java - 设置了超时的套接字有时会在读取时停止

java - 使用 writeUnshared 和 readUnshared 与套接字通信...读取我之前发送的对象,而不是我现在发送的对象

python - 将登录数据包发送到 Python 中的 Minecraft 服务器不起作用

c# - WPF 删除选项卡不处理内容?

c# - 使用linq通过文本框过滤observablecollection可以防止英文输入

c# - 使用 HttpTrigger 属性在 Azure 函数中自定义路由

java - 从直方图计算平均值和百分位数?