【问题标题】:WSACancelBlockingCall exceptionWSACancelBlockingCall 异常
【发布时间】:2010-09-07 02:35:50
【问题描述】:

好的,我的代码抛出了一个奇怪的异常,这个异常一直困扰着我。

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 服务器关闭了我的应用程序,从而取消了我所有的后台线程和阻塞方法?

【问题讨论】:

    标签: c# multithreading sockets socketexception


    【解决方案1】:

    serverSocket 是否有可能被另一个线程关闭?这将导致此异常。

    【讨论】:

    • 说是。你如何从另一个线程关闭它?套接字是否需要“易失”?
    • 不,只要其他线程有对socket对象的引用,就可以关闭它。
    【解决方案2】:

    这是我避免 WSAcancelblablabla 的示例解决方案: 将您的线程定义为全局,然后您可以使用这样的调用方法:

    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 然后停止侦听器。

    【讨论】:

    • InvokeRequired 将您的解决方案与 winforms 联系起来。如果代码在 Windows 服务中运行怎么办?
    【解决方案3】:

    这可能发生在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 之前,每隔一段时间就会发生异常。所以我的解决方案是让一切线程安全。

    【讨论】:

      【解决方案4】:

      这里也一样! 但我发现,“服务器端”上的 ReceiveBuffer 被客户端淹没了! (在我的例子中,一群 RFID 扫描仪不断向 TagCode 发送垃圾邮件,而不是在下一个 TagCode 到达之前停止发送)

      它有助于提高 ReceiveBuffers 并重新配置扫描仪...

      【讨论】:

        【解决方案5】:

        最近我在使用 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();
        }
        

        【讨论】:

        • 嗯,我看不出这对我有什么帮助(我遇到了同样的错误)。顺便说一句,“使用”模式已经为你调用了output.Close();input.Close();,所以不需要自己做,否则会被调用两次。
        猜你喜欢
        • 2013-10-06
        • 1970-01-01
        • 2021-02-03
        • 2016-09-11
        • 2021-12-05
        • 2012-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多