C# .Net套接字->;抛出System.InvalidOperationException异常
我有这个问题已经有一段时间了,从来没有真正能够解决它。只有在使用SendAsync/ReceiveAsync方法而不是Begin/EndSend套接字方法进行异步操作时,才会出现此问题 如果我有一个相当复杂的tcp套接字库,并打算用SendAsync替换BeginSend方法,但由于我遇到的问题,我总是不得不推迟。我的socket服务器正在处理超过1000个连接的客户端持续推送速度超过100mbit/sec的严重压力场景,我希望使用SendAsync方法,这样我就不会有IAsyncResult分配开销 无论如何,只要我只是发送/接收数据,一切都正常,但是在高压力情况下,当服务器尝试断开/关闭客户端时,我偶尔会遇到以下异常: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分
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分钟的高强度压力测试,一切似乎都很好(在我总是在一分钟内出现异常之前)。我会让它再运行一段时间,并希望这样做。嗨,汤姆·弗雷,你是如何修复这个异常的?我现在面临着这个例外