c# - 单独线程中 TCPClient 的内存泄漏

标签 c# multithreading memory-leaks tcpclient

我正在尝试使用以下函数从网络流中读取一些字符串数据:

static TcpClient client;
static NetworkStream nwStream;

private void conn_start_Click(object sender, EventArgs e)
{
   //Click on conn_start button starts all the connections

   client = new TcpClient(tcp_ip.Text, Convert.ToInt32(tcp_port.Text));
   nwStream = client.GetStream();
   readBuff="";
   Timer.Start();
}

string readBuff;
private void readFromConnection()
{
  string x1 = "";
  byte[] bytesToRead = new byte[client.ReceiveBufferSize];
  int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
  x1 = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
  //
  //some more code to format the x1 string      
  //
  readBuff = x1;

  bytesToRead = null;
  GC.Collect();
}

现在 readFromConnection() 函数每秒从 Timer Tick 事件调用,代码如下:

private void Timer_Tick(object sender, EventArgs e)
{
   Thread rT1 = new Thread(readFromConnection);
   rT1.Start();
   //app crashes after 40-45 min, out of memory exception.
}

这会导致一些内存泄漏。应用程序在运行 40-45 分钟后崩溃并出现 OutOfMemory 异常。

我的问题是是否有适当的方法来处理新线程,因为它只会存活 1 秒?我该如何解决这个问题?

我必须在一个新线程中运行这个函数,因为当在与 UI 相同的线程上时,它往往会卡住它。即使是很小的鼠标移动也需要几秒钟才能得到处理。

同一个角度来看,如果Tick事件在同一个线程中调用该函数,则不存在内存泄漏的问题。

private void Timer_Tick(object sender, EventArgs e)
{
   readFromConnection();
   //No memory leak here.
} 

最佳答案

不需要 Timer,您可以将 Receive 逻辑放在一个无限的 while 循环中,并且可以在每次迭代之间为线程添加一条 sleep 指令。您不应该使用 ReceiveBufferSize 从套接字流中读取数据。 ReceiveBufferSize 和对方发送了多少字节或者我有多少字节可以读取是不一样的。您可以改用 Available,即使我在从网络读取大文件时也不信任此属性。你可以使用client.Client.Receive方法,这个方法会阻塞调用线程。

private void readFromConnection()
{
    while (true)
    {
        if(client.Connected && client.Available > 0)
        {
            string x1 = string.Empty;
            byte[] bytesToRead = new byte[client.Available];
            int bytesRead = client.Client.Receive(bytesToRead);
            x1 = System.Text.Encoding.Default.GetString(bytesToRead);
        }
        Thread.Sleep(500);
    }
}

最后,关于 GC 看看 this question

关于c# - 单独线程中 TCPClient 的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47758830/

相关文章:

c# - 如何在 C# 的 "if"语句中创建多个控件为假的方法?

c# - UI线程如何知道另一个线程上的数据?

java - 取消长轮询循环的并发问题

ios - 在 iPad 上显示大型 PDF 时 UIWebView 泄漏

c# - SQL DB 中的 Asp.net session 变量

c# - 在 C# 中访问消息元素的内部嵌套 JSON 数组

c# - Visual Studio 无法识别同一项目中的命名空间

c# - 在单个 BackgroundWorker 上运行多个 DoWork 函数是否安全?

swift - 为什么在使用 ARSCNView 关闭 ViewController 时 UI 会卡住?

java - 使用 TensorFlow for Java 的内存泄漏