Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 ReceiveFromAsync泄漏SocketAsyncEventArgs?_C# 4.0_Memory Leaks_Socketasynceventargs - Fatal编程技术网

C# 4.0 ReceiveFromAsync泄漏SocketAsyncEventArgs?

C# 4.0 ReceiveFromAsync泄漏SocketAsyncEventArgs?,c#-4.0,memory-leaks,socketasynceventargs,C# 4.0,Memory Leaks,Socketasynceventargs,我有一个客户端应用程序,它通过UDP或TCP套接字从服务器接收视频流 最初,当使用.NET2.0编写时,代码使用的是BeginReceive/EndReceive和IAsyncResult。 客户端在自己的窗口中显示每个视频,并使用自己的线程与服务器通信。 但是,由于客户机应该运行很长一段时间,并且可能同时有64个视频流,因此每次调用data receive回调时分配的IAsyncResult对象存在“内存泄漏” 这会导致应用程序最终耗尽内存,因为GC无法及时处理块的释放。我使用VS2010性能

我有一个客户端应用程序,它通过UDP或TCP套接字从服务器接收视频流

最初,当使用.NET2.0编写时,代码使用的是BeginReceive/EndReceive和IAsyncResult。 客户端在自己的窗口中显示每个视频,并使用自己的线程与服务器通信。 但是,由于客户机应该运行很长一段时间,并且可能同时有64个视频流,因此每次调用data receive回调时分配的IAsyncResult对象存在“内存泄漏”

这会导致应用程序最终耗尽内存,因为GC无法及时处理块的释放。我使用VS2010性能分析器验证了这一点

因此,我修改了代码以使用SocketAsyncEventArgs和ReceiveFromAsync(UDP大小写)。 但是,我仍然看到内存块在以下位置增长:

System.Net.Sockets.Socket.ReceiveFromAsync(class System.Net.Sockets.SocketAsyncEventArgs)
我已经阅读了所有关于实现代码的示例和帖子,但仍然没有解决方案

下面是我的代码的样子:

// class data members
private byte[] m_Buffer = new byte[UInt16.MaxValue];
private SocketAsyncEventArgs m_ReadEventArgs = null;
private IPEndPoint m_EndPoint; // local endpoint from the caller
初始化

m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_Socket.Bind(m_EndPoint);
m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, MAX_SOCKET_RECV_BUFFER);

//
// initalize the socket event args structure. 
//
m_ReadEventArgs = new SocketAsyncEventArgs();
m_ReadEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(readEventArgs_Completed);
m_ReadEventArgs.SetBuffer(m_Buffer, 0, m_Buffer.Length);
m_ReadEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
m_ReadEventArgs.AcceptSocket = m_Socket;
读取完成处理程序:

bool waitForEvent = m_Socket.ReceiveFromAsync(m_ReadEventArgs);
if (!waitForEvent)
{
    readEventArgs_Completed(this, m_ReadEventArgs);
}
private void readEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
    if (e.BytesTransferred == 0 || e.SocketError != SocketError.Success)
    {
        //
        // we got error on the socket or connection was closed
        //
        Close();
        return;
     }

     try
     {
          // try to process a new video frame if enough data was read
          base.ProcessPacket(m_Buffer, e.Offset, e.BytesTransferred);
     }
     catch (Exception ex)
     {
          // log and error
     }

     bool willRaiseEvent = m_Socket.ReceiveFromAsync(e);

     if (!willRaiseEvent)
     {
         readEventArgs_Completed(this, e);
     }
}
基本上,代码运行良好,我可以完美地看到视频流,但这次泄漏确实令人痛苦

我错过什么了吗


非常感谢

而不是在
之后递归调用
readEventArgs\u Completed
!willRaiseEvent
使用
goto
返回方法的顶部。我注意到,当我有一个类似于您的模式时,我正在慢慢地占用堆栈空间。

SocketAsyncEventArgs
Socket
实现
IDisposable
…您是否确保这些对象已被释放?我正在重用m_ReadEventArgs。我认为使用SocketAsyncEventArgs的全部意义并不是每次调用都有一个新对象,或者是吗?谢谢你的回复。