Patrick
Patrick

Reputation: 420

Server exception on close (blocking operation interrupted)

My server app runs perfectly fine until I try to close it. At that point i'm getting two exceptions. I put in a try-catch to try and debug them, and go the following:

The first exception is: A blocking operation was interrupted by a call to WSACancelBlockingCall and the 2nd one is Not listening. You must call the Start() method before calling this method.

Here's a snippet from where the exception occurs:

    private void ListenForClients()
    {
        this.tcpListener.Start();            

        while (true)
        {
            try
            {
                TcpClient client = this.tcpListener.AcceptTcpClient(); // EXCEPTION OCCURS HERE
                string clientIPAddress = "" + IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
                ClientIPLabel.Text = clientIPAddress;
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
            catch (Exception e)

            {
                MessageBox.Show(e.Message.ToString());
            }                              
        }
    }

I'm not sure if it might be because I'm missing something here or not, but here's my code for closing the server app:

    private void ShutdownServer_Click(object sender, EventArgs e)
    {
        this.tcpListener.Stop();
            Application.Exit();
    }

I'm also unable to run this app from a release build; it just freezes as soon as I try to run it, and I need to restart my machine in order to close it (I can close the form, but the process stays running in task manager and "end task" doesn't close it). I'm assuming these exceptions are likely what's causing that issue, since I can run the debug build just fine.

Upvotes: 4

Views: 5292

Answers (1)

usr
usr

Reputation: 171246

The exception is normal. It happens because you are concurrently closing a listener that is accepting at that time.

Catching that exception and throwing it away is the right choice. I would do it like this to make the catch safer:

//Stop:
isStopping = true;
this.tcpListener.Stop();

//...

private void ListenForClients()
{
    this.tcpListener.Start();            

    while (true)
    {
        try
        {
            TcpClient client = this.tcpListener.AcceptTcpClient();
            //...
        }
        catch (Exception e)
        {
            if (!isStopping) throw; //don't swallow too much!
        }                              
    }
}

There is no cleaner (exception free) way to interrupt socket operations. (Yes, this is a bad situation.)

Regarding the freezing issue, this is not normal and not a .NET issue (.NET can't prevent a process from being killed, there is no such Windows API). Windows bug, OS corruption, Anti Virus, Firewall, ...

Upvotes: 4

Related Questions