D'accord, j'ai une exception étrange lancée par mon code qui me dérange depuis des siècles.
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 n'est pas d'une grande aide sur ce point : http://msdn.microsoft.com/en-us/library/ms741547(VS.85).aspx et je ne sais même pas par où commencer pour résoudre ce problème. Il se produit seulement 4 ou 5 fois par jour, et jamais dans notre environnement de test. Uniquement sur les sites de production, et sur TOUS les sites de production.
J'ai trouvé plein de publications posant des questions sur cette exception, mais aucune réponse définitive sur ce qui la provoque, et comment la gérer ou l'éviter.
Le code s'exécute dans un thread d'arrière-plan séparé, la méthode démarre :
public virtual void Startup()
{
TcpListener serverSocket= new TcpListener(new IPEndPoint(bindAddress, port));
serverSocket.Start();
ensuite, je boucle en mettant toutes les nouvelles connexions en tant que tâches dans un pool de threads séparé. Cela devient plus compliqué en raison de l'architecture de l'application, mais en gros :
while (( socket = serverSocket.AcceptTcpClient()) !=null) //Drôle d'exception ici
{
connectionHandler = new ConnectionHandler(socket, mappingStrategy);
pool.AddJob(connectionHandler);
}
}
À partir de là, le pool
a ses propres threads qui s'occupent de chaque tâche dans leur propre thread, séparément.
Je comprends qu'AcceptTcpClient() est un appel bloquant, et que d'une manière ou d'une autre, winsock dit au thread d'arrêter de bloquer et de continuer l'exécution.. mais pourquoi? Et que suis-je censé faire? Juste attraper l'exception et l'ignorer?
Eh bien, je pense qu'un autre thread ferme le socket, mais ce n'est certainement pas de mon code. Ce que j'aimerais savoir, c'est : est-ce que ce socket est fermé par le client connecté (de l'autre côté du socket) ou est-ce fermé par mon serveur. Parce que tel que c'est actuellement, chaque fois que cette exception se produit, cela ferme mon port d'écoute, fermant ainsi efficacement mon service. Si cela se produit à distance, c'est un gros problème.
Alternativement, cela pourrait-il être simplement le serveur IIS arrêtant mon application, et annulant ainsi tous mes threads d'arrière-plan et méthodes bloquantes?