gpt4 book ai didi

c# - .Net 套接字 -> 抛出 System.InvalidOperationException

转载 作者:可可西里 更新时间:2023-11-01 02:49:55 24 4
gpt4 key购买 nike

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

如果有一个相当复杂的 tcp 套接字库,并且打算用 SendAsync 替换 BeginSend 方法,但由于我遇到的问题,我总是不得不推迟它。我的套接字服务器正在处理超过 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 框架内,而且我也无能为力,因为它会导致我的服务器崩溃。

因为这只发生在我调用我的关闭过程时,我猜测它与在套接字上调用 Shutdown 而它仍然有一个读/写过程挂起有关。但是,我也尝试延迟调用 shutdown,直到所有读/写 Send/ReceiveAsync 调用返回,然后再调用 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 分钟的重压力测试,一切似乎都很好(在我总是在一分钟内得到该异常之前)。我会让它再运行一段时间,希望它能成功。

关于c# - .Net 套接字 -> 抛出 System.InvalidOperationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1625887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com