Исключение WSACancelBlockingCall - PullRequest
       9

Исключение WSACancelBlockingCall

41 голосов
/ 28 августа 2008

Хорошо, у меня есть странное исключение из моего кода, который беспокоит меня целую вечность.

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, закрывающий мое приложение и, таким образом, отменяющий все мои фоновые потоки и методы блокировки?

Ответы [ 5 ]

41 голосов
/ 29 августа 2008

Возможно ли, что serverSocket закрывается из другого потока? Это вызовет это исключение.

6 голосов
/ 06 декабря 2011

Это мой пример решения, чтобы избежать WSAcancelblablabla: Определите ваш поток как глобальный, тогда вы можете использовать метод invoke следующим образом:

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 и остановите слушатель.

4 голосов
/ 04 ноября 2008

Это может произойти на 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 было установлено в true Поэтому для меня было решено сделать все безопасно.

3 голосов
/ 26 августа 2011

То же самое здесь! Но я понял, что ReceiveBuffer на стороне сервера был залит от клиентов! (В моем случае группа RFID-сканеров, которые продолжали рассылать спам TagCode, вместо того, чтобы прекратить отправку до получения следующего TagCode)

Помогло поднять ReceiveBuffers и перенастроить сканеры ...

0 голосов
/ 26 июня 2018

Совсем недавно я видел это исключение при использовании HttpWebRequest для PUT большого файла и истечения времени ожидания.

Использование следующего кода до тех пор, пока время загрузки> 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...