首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReceiveFromAsync泄漏SocketAsyncEventArgs?

ReceiveFromAsync泄漏SocketAsyncEventArgs?
EN

Stack Overflow用户
提问于 2014-02-06 20:40:58
回答 1查看 1.6K关注 0票数 2

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

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

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

因此,我修改了代码以使用SocketAsyncEventArgs和ReceiveFromAsync (UDP情况)。但是,我仍然看到内存块在以下方面有所增长:

代码语言:javascript
复制
System.Net.Sockets.Socket.ReceiveFromAsync(class System.Net.Sockets.SocketAsyncEventArgs)

我已经阅读了有关实现代码的所有示例和帖子,但仍然没有解决方案。

下面是我的代码的样子:

代码语言:javascript
复制
// 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

初始化

代码语言:javascript
复制
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;

启动读取过程:

代码语言:javascript
复制
bool waitForEvent = m_Socket.ReceiveFromAsync(m_ReadEventArgs);
if (!waitForEvent)
{
    readEventArgs_Completed(this, m_ReadEventArgs);
}

读取完成处理程序:

代码语言:javascript
复制
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);
     }
}

基本上,代码工作得很好,我能很好地看到视频流,但是这个漏洞真的很痛苦。

我错过了什么吗??

非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2014-08-21 18:06:38

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21613604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档