gpt4 book ai didi

c# - 需要一个更优雅的模式来关闭 TcpListener

转载 作者:太空宇宙 更新时间:2023-11-03 17:04:16 26 4
gpt4 key购买 nike

我有一个 TcpListener,它在关闭时会导致所有进行中的客户端在尝试调用 EndAcceptTcpClient 时抛出以下异常。是否可以使用更优雅的模式来允许所有现有客户端连接在 TcpListener 完全关闭之前完成?

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'. at System.Net.Sockets.Socket.EndAccept(IAsyncResult asyncResult) at System.Net.Sockets.TcpListener.EndAcceptTcpClient(IAsyncResult asyncResult)

这是监听器设置的示例:

private TcpListener _requestListener;

requestListener = new TcpListener(endPoint);

requestListener.Start(1000);

requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, null);

当我试图关闭监听器时,我调用以下命令。这就是导致上述异常的原因。

if (_requestListener != null)
{
_requestListener.Stop();
}

这是处理回调的代码示例,回调最终通过调用监听器 Stop() 方法来实现

private void ServiceRequestInstanceHandler(IAsyncResult result)
{
try
{
using (TcpClient client = _requestListener.EndAcceptTcpClient(result))
{
ProcessRequest(client);
client.Close();
}

//Prepare to accept the next message
_requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, null);
}
catch (Exception ex)
{
if (_logger.IsErrorEnabled)
_logger.Error("An error occured while processing a service request. ", ex);
}
}

最佳答案

我相信要避免错误,您需要将 requestListener 对象传递给 BeginAcceptTcpClient,如下所示:

requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, requestListener);

供引用:http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.beginaccepttcpclient.aspx

我个人也会重写您的方法,让您的服务器在像这样处理其他客户端之前接受一个新客户端:

private void ServiceRequestInstanceHandler(IAsyncResult result)
{
try
{
// You should probably check for a null result here, just in case
if(result == null)
{
throw new Exception("Result is null, cannot continue");
}
using (TcpClient client = _requestListener.EndAcceptTcpClient(result))
{
// Remember this line returns immediately/does not block
_requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, _requestListener);
ProcessRequest(client);
client.Close();
}
}
catch (Exception ex)
{
if (_logger.IsErrorEnabled)
_logger.Error("An error occured while processing a service request. ", ex);
}
}

IIRC,异步内容在单独的线程上运行。

注意:上面的代码我没有测试过,但应该可以解决你的问题:)

HTH

关于c# - 需要一个更优雅的模式来关闭 TcpListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8668169/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com