56

Ok, I have a strange exception thrown from my code that's been bothering me for ages.

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 isn't terribly helpful on this : http://msdn.microsoft.com/en-us/library/ms741547(VS.85).aspx and I don't even know how to begin troubleshooting this one. It's only thrown 4 or 5 times a day, and never in our test environment. Only in production sites, and on ALL production sites.

I've found plenty of posts asking about this exception, but no actual definitive answers on what is causing it, and how to handle or prevent it.

The code runs in a separate background thread, the method starts :

public virtual void Startup()
    {
     TcpListener serverSocket= new TcpListener(new IPEndPoint(bindAddress, port));    
        serverSocket.Start();

then I run a loop putting all new connections as jobs in a separate thread pool. It gets more complicated because of the app architecture, but basically:

   while (( socket = serverSocket.AcceptTcpClient()) !=null) //Funny exception here
    {
         connectionHandler = new ConnectionHandler(socket, mappingStrategy);
         pool.AddJob(connectionHandler);
    }
  }

From there, the pool has it's own threads that take care of each job in it's own thread, separately.

My understanding is that AcceptTcpClient() is a blocking call, and that somehow winsock is telling the thread to stop blocking and continue execution.. but why? And what am I supposed to do? Just catch the exception and ignore it?


Well, I do think some other thread is closing the socket, but it's certainly not from my code. What I would like to know is: is this socket closed by the connecting client (on the other side of the socket) or is it closed by my server. Because as it is at this moment, whenever this exception occurs, it shutsdown my listening port, effectively closing my service. If this is done from a remote location, then it's a major problem.

Alternatively, could this be simply the IIS server shutting down my application, and thus cancelling all my background threads and blocking methods?

6 Answers 6

58

Is it possible that the serverSocket is being closed from another thread? That will cause this exception.

Sign up to request clarification or add additional context in comments.

2 Comments

Say it is. How do you close it from another thread? Does the socket need to be 'volatile'?
No, as long as the other thread has a reference to the socket object, it can close it.
7

This is my example solution to avoid WSAcancelblablabla: Define your thread as global then you can use invoke method like this:

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();
    }

After you invoke it, close the thread first then the forever loop flag so it block further waiting (if you have it), then close tcpclient then stop the listener.

1 Comment

InvokeRequired ties your solution to winforms. What if code is running in a windows service?
7

This could happen on a serverSocket.Stop(). Which I called whenever Dispose was called.

Here is how my exception handling for the listen thread looked like:

try
{
    //...
}
catch (SocketException socketEx)
{    
    if (_disposed)
        ar.SetAsCompleted(null, false); //exception because listener stopped (disposed), ignore exception
    else
        ar.SetAsCompleted(socketEx, false);
}

Now what happened was, every so often the exception would occur before _disposed was set to true. So the solution for me was to make everything thread safe.

Comments

3

Same here! But i figured out, that the ReceiveBuffer on 'server-side' was flooded from the clients! (In my case a bunch of RFID-Scanners, who kept spamming the TagCode, instead of stop sending until next TagCode arrives)

It helped to raise the ReceiveBuffers and reconfigure the scanners...

Comments

1

We saw this WSACancelBlockingCall exception with SSH.NET. This exception was thrown, then caught internally by SSH.NET.

In Visual Studio, Debug -> Windows -> Exception Settings might be set so that you see the error, but it is being handled correctly within its own code. When I reset the settings to the Default, we no longer saw the internal error.

1 Comment

Thanks! This was exactly my problem, forgetting I had reset the exception settings.
0

More recently I saw this exception when using HttpWebRequest to PUT a large file and the Timeout period was passed.

Using the following code as long as your upload time > 3 seconds it will cause this error as far as I could see.

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();
}

1 Comment

Hmm, I fail to see how this can help me (I'm having the same error). Btw, the "using" pattern already call output.Close(); and input.Close(); for you, so no need do it yourself, it will be called twice otherwise.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.