WSACancelBlockingCall异常
时间:2020-03-05 18:44:17 来源:igfitidea点击:
好的,我的代码抛出了一个奇怪的异常,困扰了我好久了。
System.Net.Sockets.SocketException: A blocking operation was interrupted by a call to WSACancelBlockingCall at System.Net.Sockets.Socket.Accept() at System.Net.Sockets.TcpListener.AcceptTcpClient()
MSDN对此并不十分有用:http://msdn.microsoft.com/zh-cn/library/ms741547(VS.85).aspx,我什至不知道如何开始对这一问题进行故障排除。每天只抛出4到5次,并且从来没有在我们的测试环境中抛出过。仅在生产站点和所有生产站点上。
我发现很多帖子都在询问这种异常,但是对于导致它的原因以及如何处理或者预防它,没有确切的确切答案。
代码在单独的后台线程中运行,方法开始:
public virtual void Startup() { TcpListener serverSocket= new TcpListener(new IPEndPoint(bindAddress, port)); serverSocket.Start();
然后运行一个循环,将所有新连接作为作业放入单独的线程池中。由于应用程序的架构,它变得更加复杂,但是基本上:
while (( socket = serverSocket.AcceptTcpClient()) !=null) //Funny exception here { connectionHandler = new ConnectionHandler(socket, mappingStrategy); pool.AddJob(connectionHandler); } }
从那里,pool
有自己的线程,分别在自己的线程中处理每个作业。
我的理解是AcceptTcpClient()是一个阻塞的调用,并且winsock以某种方式告诉线程停止阻塞并继续执行..但是为什么呢?我该怎么办?只是捕获异常并忽略它?
好吧,我确实认为其他一些线程正在关闭套接字,但是这肯定不是我的代码引起的。
我想知道的是:此套接字是由连接客户端(在套接字的另一侧)关闭的还是由我的服务器关闭的。因为就目前而言,每当发生此异常时,它都会关闭我的侦听端口,从而有效地关闭我的服务。如果这是从远程位置完成的,那么这将是一个主要问题。
或者,这可能仅仅是IIS服务器关闭我的应用程序,从而取消了我的所有后台线程和阻止方法吗?
解决方案
回答
serverSocket是否可能正在从另一个线程关闭?这将导致此异常。
回答
这可能发生在serverSocket.Stop()
上。每当调用Dispose时,我都会调用它。
这是我对侦听线程的异常处理的样子:
try { //... } catch (SocketException socketEx) { if (_disposed) ar.SetAsCompleted(null, false); //exception because listener stopped (disposed), ignore exception else ar.SetAsCompleted(socketEx, false); }
现在发生的是,在将_disposed设置为true之前,异常情况经常会发生。所以对我来说,解决方案是使所有线程安全。