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之前,异常情况经常会发生。所以对我来说,解决方案是使所有线程安全。