I've been experimenting on UDP for a few days and in one of the UDP projects, Client, I've a ConcurrentQueue where client stores byte[] in a function receiveOrder
void receiveOrder()
{
var buffer = new byte[Constants.ORDER_SIZE];
while (!receiveSource.IsCancellationRequested)
{
tradeClient.Receive(buffer);
recCount++;
orderQueue.Enqueue(buffer.ToArray());
}
}
and dequeues byte[] in another function processOrder:
void processOrder()
{
while (!receiveSource.IsCancellationRequested)
{
if (orderQueue.Count > 0)
{
byte[] buffer;
while (!orderQueue.TryDequeue(out buffer)) { }
Orders.Add(Encoding.UTF8.GetString(buffer));
count++;
}
}
}
I start both of these functions with these:
receiveSource = new CancellationTokenSource();
Task.Run(receiveOrder, receiveSource.Token);
Task.Run(processOrder, receiveSource.Token);
I've used 2 PCs in my experiment one with IP 1**.**.***.101 and the other 1**.**.***.105. Server and a Client were on 1**.**.***.101 and on 1**.**.***.105 I'd only the client. Both Client and Server are .Net5 application and here's what it does and here's the project.
I've no problem with Client on 1**.**.***.105 BUT, it looks like, the Client on 1**.**.***.101 fails either in enqueuing or dequeuing.
EDIT
Do I really need ConcurrentQueue where only one thread is assigned for enqueuing and only one other thread is dequeuing or a normal Queue will do the job perfectly in such scenario?
Notes for reference
Over the past couple of days what I've learnt is: these blocking Receive or continuous processing, as in processOrder, are long task and I shouldn't use Task in these cases because Task with long running option under the hood creates a new Thread. There're two options, excluding sequential Socket.Select, 1) ReceiveAsync with a Callback (eg. SocketAsyncEventArgs) or Thread.
Synchronous (blocking Receive) operation with Thread is the most efficient BUT it takes about a MB of RAM for each Thread. ReceiveAsync uses ThreadPool (Limited Number of Thread and as a result it lets us have more client/connection) for the Callback and keeps polling in the background to see which socket has data and fire the OnCompleted event so it's less efficient.
