WSACancelBlockingCallexception
好的,我有一个奇怪的exception从我的代码中抛出,一直困扰着我很多年。
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/en-us/library/ms741547(VS.85).aspx我甚至不知道如何开始解决这个问题。 它每天只能投掷四五次,从来没有在我们的testing环境中。 只在生产现场和所有生产现场。
我发现了很多关于这个exception的post,但是没有对引起这个exception的确切答案,以及如何处理或者阻止它。
代码运行在一个单独的后台线程中,方法开始:
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告诉线程停止阻止,并继续执行..但为什么? 我该怎么做? 只是赶上例外,忽略它?
那么,我认为其他线程正在closures套接字,但它肯定不是我的代码。 我想知道的是:这个套接字是由连接客户端(在套接字的另一端)closures,还是由我的服务器closures。 因为就在这个时候,每当发生这种exception,它就会closures我的监听端口,从而有效地closures我的服务。 如果这是从远程位置完成的,那么这是一个主要问题。
或者,这可能是简单的IIS服务器closures我的应用程序,从而取消所有我的后台线程和阻止方法?
是否有可能从另一个线程closuresserverSocket? 这将导致这个例外。
这是我的示例解决scheme,以避免WSAcancelblablabla:定义您的线程为全球,那么你可以使用像这样的调用方法:
private void closinginvoker(string dummy) { if (InvokeRequired) { this.Invoke(new Action<string>(closinginvoker), new object[] { dummy }); return; } t_listen.Abort(); client_flag = true; c_idle.Close(); listener1.Stop(); }
在调用它之后,先closures线程,然后closures永久循环标志,这样可以阻止进一步的等待(如果有的话),然后closurestcpclient然后停止监听器。
这可能发生在serverSocket.Stop()
。 当Dispose
被调用时,我调用了这个Dispose
。
下面是我如何处理listen函数的exception:
try { //... } catch (SocketException socketEx) { if (_disposed) ar.SetAsCompleted(null, false); //exception because listener stopped (disposed), ignore exception else ar.SetAsCompleted(socketEx, false); }
现在发生了什么事情,在_disposed
被设置为true之前,经常发生exception。 所以对我来说,解决scheme就是让所有线程都安全。
同样在这里! 但是我发现,'服务器端'上的ReceiveBuffer被客户端淹没了! (在我的情况下,一堆RFID扫描器,不断发送TagCode垃圾邮件,而不是停止发送,直到下一个TagCode到达)
它有助于提高ReceiveBuffers并重新configuration扫描仪…