Open wmjordan opened 7 years ago
Do you have a test case I can reproduce this issue?
Thank you for replying. It was hard to reproduce in a short time. I was trying to mock up a stress test model to reproduce this issue and I would post it here when it is finished. Meanwhile, I moved the application to another machine and see whether it would occur there as well.
And which version do you use?
Sorry to have forgotten to mention the versions. All assemblies were compiled from the newest source code from your repositories. I'd removed the dependency from NuGet and used the compiled assemblies in the ClientEngine project.
The projects targeting .NET 4.0 were used to compile the assemblies. And the operating system was Windows Server 2008.
I studied the source code of EasyClientBase
and AsyncTcpSession
.
I found that the AsyncTcpSession.SendInternal
, AsyncTcpSession.StartReceive
and AsyncTcpSession.SetBuffer
can be using the same instance of SocketAsyncEventArgs
without locking. However, the SocketAsyncEventArgs
internally excludes data-sending, data-receiving and buffer-setting operations mutually. Those three operations can not proceed at the same time.
Consequently, the SetBuffer
method can fail when the Socket
is using the SocketAsyncEventArgs
instance to receive or send data and therefore the InvalidOperationException
is thrown.
Thread synchronization shall be deployed to avoid the above problem.
I think send and receive have different SocketAsyncEventArgs instances: private SocketAsyncEventArgs m_SocketEventArgs; private SocketAsyncEventArgs m_SocketEventArgsSend;
The issue happened to my applications when the client was attempting to receive data.
Could it be possible that the SetBuffer
method was called when a socket was using the same SocketAsyncEventArgs
instance to receive data?
Is there a way to produce this issue easily?
Not so easy, I am afraid. But, I will still try to make a test case for you, or fix this issue at my side and commit a pull request here if I am lucky.
重连多次,大概10次左右。
protected override void SetBuffer(ArraySegment
if (m_SocketEventArgs != null)
{
m_SocketEventArgs.SetBuffer(bufferSegment.Array, bufferSegment.Offset, bufferSegment.Count);
}
}
m_SocketEventArgs.SetBuffer 这里报这个错误。连接上之后,已经在接收数据时候,报错。
I was using the easy client to send some data. The source data was pushed into the application from about 20 incoming TCP connections, processed by a
AppServer
of SocketEngine, which called anEasyClient
to send data to another place. The client was under a pretty low workload, sending about 2 packages a second only. However, it occasionally threw a "System.InvalidOperationException" and the application became unusable afterward.The following was the stack trace related to the exception. I could not found a line relative to my own code, I deduced that it was in another thread, spawned from the
EasyClient
.