|
Member 7931978 wrote: This only works if you have only two calls to OnReceive() happening at once, no The key here is the BeginReceive call, which tells the .NET socket support to call the OnReceive delegate asynchronously on a thread pool thread when a message is received. In my initial code that has the bug, I was issuing the second BeginReceive call to start receipt of the next message before I'd finished processing the current message. Under high load conditions, this could cause the OnReceive handler to be called recursively. The actual message handling would then be processed in reverse order as the stack unwound.Member 7931978 wrote: what guarantee do you have that the "correct" thread will be the next one to acquire the lock? The lock in this case was protecting the socket connection, so there is no 'correct' thread per se. The .NET socket support can call the asynchronous delegate on any thread it has available. The lock is essentially a critical section.
Software Zen: delete this;
|
|
|
|
|
Sorry, but this code violates causality... it won't compile.
|
|
|
|
|
That kind of error is funny.
For many years a C++ application worked. It used a non initialized pointer but, for many time, it was always null (calling the right initialization).
One day it simple decided to get garbage.
|
|
|
|
|
I assume this had something to do with IAsyncResult.CompletedSynchronously [^] (possibly derived from Socket.Available [^])?
Interesting because under extreme and consistent load this means that the async loop could cause a StackOverflowException (even with your fixed code); I wonder if there is a way to turn off this 'optimization' without having to resort to:
private void StartAsyncReadLoop()
{
ReadAsyncLoop(null);
}
private void ReadAsyncLoop(IAsyncResult state)
{
try
{
if (state != null)
{
var length = _socket.EndReceive(state);
}
if (state == null || !state.CompletedSynchronously)
_socket.BeginReceive(..., ReadAsyncLoop, null);
else
ThreadPool.QueueUserWorkItem(_ => _socket.BeginReceive(..., ReadAsyncLoop, null));
}
catch (SocketException ex)
{
}
}
I wonder if Socket.UseOnlyOverlappedIO [^] would have an effect on this, considering Overlapped IO is my 'asyncy' than IOCP.
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chinese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|