Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .Net套接字->;抛出System.InvalidOperationException异常_C#_Sockets_Asynchronous_Tcp - Fatal编程技术网

C# .Net套接字->;抛出System.InvalidOperationException异常

C# .Net套接字->;抛出System.InvalidOperationException异常,c#,sockets,asynchronous,tcp,C#,Sockets,Asynchronous,Tcp,我有这个问题已经有一段时间了,从来没有真正能够解决它。只有在使用SendAsync/ReceiveAsync方法而不是Begin/EndSend套接字方法进行异步操作时,才会出现此问题 如果我有一个相当复杂的tcp套接字库,并打算用SendAsync替换BeginSend方法,但由于我遇到的问题,我总是不得不推迟。我的socket服务器正在处理超过1000个连接的客户端持续推送速度超过100mbit/sec的严重压力场景,我希望使用SendAsync方法,这样我就不会有IAsyncResult分

我有这个问题已经有一段时间了,从来没有真正能够解决它。只有在使用SendAsync/ReceiveAsync方法而不是Begin/EndSend套接字方法进行异步操作时,才会出现此问题

如果我有一个相当复杂的tcp套接字库,并打算用SendAsync替换BeginSend方法,但由于我遇到的问题,我总是不得不推迟。我的socket服务器正在处理超过1000个连接的客户端持续推送速度超过100mbit/sec的严重压力场景,我希望使用SendAsync方法,这样我就不会有IAsyncResult分配开销

无论如何,只要我只是发送/接收数据,一切都正常,但是在高压力情况下,当服务器尝试断开/关闭客户端时,我偶尔会遇到以下异常:

    System.InvalidOperationException was unhandled
  Message=Cannot apply a context that has been marshaled across AppDomains, that was not acquired through a Capture operation or that has already been the argument to a Set call.
  Source=mscorlib
  StackTrace:
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
       at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
       at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
  InnerException: 
我无法在任何地方捕捉到这个异常,因为它似乎发生在.NET framework中,我无法对它崩溃我的服务器做任何事情

由于这只发生在我调用shutdown过程时,我猜这与在套接字上调用shutdown有关,而它仍然有一个读/写过程挂起。 但是,我也尝试延迟调用shutdown,直到所有读/写发送/接收异步调用都返回,然后再调用shutdown,但这也没有帮助

以下是我如何尝试关闭套接字:

        private void InternalDisconnect(SocketError socketError)
    {
        lock (shutdownLock)
        {
            if (isShutdown)
                return;

            isShutdown = true;
        }

        allowSend = false;
        SocketError = socketError;

        ThreadPool.QueueUserWorkItem(delegate
                                         {
                                             lock (padLock)
                                             {
                                                 try
                                                 {
                                                     if (TcpSocketStatus == TcpSocketStatus.Disconnected)
                                                         return;

                                                     TcpSocketStatus = TcpSocketStatus.Disconnecting;

                                                     if (asyncSendArgs != null)
                                                     {
                                                         asyncSendArgs.Completed -= SendCompleted;
                                                         asyncSendArgs.SetBuffer(null, 0, 0);
                                                         asyncSendArgs.Dispose();
                                                     }

                                                     if (asyncReceiveArgs != null)
                                                     {
                                                         asyncReceiveArgs.Completed -= ReceiveCompleted;
                                                         asyncReceiveArgs.SetBuffer(null, 0, 0);
                                                         asyncReceiveArgs.Dispose();
                                                     }

                                                     try
                                                     {
                                                         bufferedSender.Clear();

                                                         Socket.Shutdown(SocketShutdown.Both);

                                                         if (Socket.Connected)
                                                         {
                                                             Socket.Disconnect(true);
                                                         }
                                                     }
                                                     catch
                                                     {
                                                     }

                                                     try
                                                     {
                                                         Socket.Close();
                                                     }
                                                     catch
                                                     {
                                                     }

                                                     TcpSocketStatus = TcpSocketStatus.Disconnected;

                                                     if (socketError != SocketError.Success)
                                                     {
                                                         if (log.IsDebugEnabled)
                                                             log.Debug("SocketDisconnected\tSocketError:{0}", socketError);
                                                     }
                                                     else
                                                     {
                                                         if (log.IsDebugEnabled)
                                                             log.Debug("SocketDisconnected");
                                                     }

                                                     DisconnectTime = DateTime.UtcNow;

                                                     if (TcpSocketDisconnected != null)
                                                         TcpSocketDisconnected(this);
                                                 }
                                                 catch (Exception ex)
                                                 {
                                                     log.ErrorException("InternalDisconnect", ex);
                                                 }
                                             }
                                         });
    }

好吧,出于某种原因,问问题总是对我有帮助,因为我总是在很短的时间内就想清楚事情:/

似乎asyncSendArgs.SetBuffer(null,0,0);是罪魁祸首。 尽管另一段代码应该确保在调用InternalDisconnect之前没有未完成的异步操作,但似乎仍然有,并且在使用缓冲区时更改缓冲区肯定会导致问题。
到目前为止,我已经进行了15分钟的高强度压力测试,一切似乎都很好(在我总是在一分钟内出现异常之前)。我会让它再运行一段时间,并希望这样做。

嗨,汤姆·弗雷,你是如何修复这个异常的?我现在面临着这个例外