题
好吧,我有个奇怪的异常引发我的代码这就是一直困扰我的年龄。
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 我甚至不知道如何开始进行故障排除这一点。这只是扔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告诉线,以停止阻止和继续执行..但为什么?我该怎么做?正好赶上的例外,并忽略?
嗯,我的确认为其他一些线被关闭插座,但它肯定不是从我的代码。我想知道的是:这是座封闭连接客户(在另一侧的座),或者是它关闭过我的服务器。因为,因为它是在这个时刻,每当这种异常情况发生时,它shutsdown我听口,有效地封闭我的服务。如果这样做从远程地点,然后,它的一个主要问题。
或者,这可能是简单地IIS服务器关闭我的应用程序,并因此取消我所有的背景线和阻挡的方法吗?
解决方案
它是可能的,serverSocket正在关闭的另一个线?这将导致这种例外。
其他提示
这是我的例子解决方案,以避免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();
}
之后你调用,靠近第一线然后永远的环标志所以这块进一步的等待时间(如果有的话),然后关闭tcpclient然后停止监听器。
这可能发生在 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
被设置为真实的。这样的解决方案我就是让一切线的安全。
同样的在这里!但我想通了,ReceiveBuffer在服务器侧'被水淹没了从客户!(在我的情况一大堆的无线射频扫描仪,保持垃圾邮件的TagCode,而不是停止发送到下TagCode达)
它有助于提高ReceiveBuffers和重新配置的扫描仪...
最近我看到这种例外时采用HttpWebRequest把一个很大的文件和超时期获得通过。
使用下列代码,只要你上传的时间>3秒钟,这将导致这一错误,因为太远,因为我能看到的。
string path = "Reasonably large file.dat";
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
System.Net.HttpWebRequest req = (HttpWebRequest)System.Net.HttpWebRequest.Create("Some URL");
req.Method = "PUT";
req.Timeout = 3000; //3 seconds, small timeout to demonstrate
long length = new System.IO.FileInfo(path).Length;
using (FileStream input = File.OpenRead(path))
{
using (Stream output = req.GetRequestStream())
{
long remaining = length;
int bytesRead = 0;
while ((bytesRead = input.Read(buffer, 0, (int)Math.Min(remaining, (decimal)bufferSize))) > 0)
{
output.Write(buffer, 0, bytesRead);
remaining -= bytesRead;
}
output.Close();
}
input.Close();
}