Хорошо, у меня есть странное исключение из моего кода, который беспокоил меня целую вечность.
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 сообщает потоку прекратить блокировку и продолжить выполнение.. но почему? И что я должен делать? Просто поймайте исключение и проигнорируйте его?
Ну, я думаю, что какой-то другой поток закрывает сокет, но это, конечно, не из моего кода. Я хотел бы знать следующее: этот сокет закрыт подключающимся клиентом (с другой стороны сокета) или закрыт моим сервером. Потому что, как и в этот момент, всякий раз, когда возникает это исключение, он отключает мой прослушивающий порт, эффективно закрывая мой сервис. Если это делается из удаленного места, то это серьезная проблема.
В качестве альтернативы, может ли это быть просто сервер IIS, завершающий мое приложение и, таким образом, отменя все мои фоновые потоки и методы блокировки?