I noticed the today that my one application im developing is seriously growing in memory. So I did a Visual Studio Memory Profile and I found the following results:
Function Name Inclusive Allocations Exclusive Allocations Inclusive Bytes Exclusive Bytes
System.Net.Sockets.Socket.BeginSend(uint8[],int32,int32,valuetype System.Net.Sockets.SocketFlags,valuetype System.Net.Sockets.SocketError&,class System.AsyncCallback,object) 3 192 569 3 192 561 635 307 885 635 307 621
This was on top of the memory Usage with ~600Meg
This doesnt seem correct to me and im Not sure why it is so?
Here is my send function:
private void SendSignal(Byte[] signal)
{
if (state.WorkSocket.Connected)
{
try
{
state.WorkSocket.BeginSend(signal, 0, signal.Length, 0, new AsyncCallback(SendCallback), state.WorkSocket);
}
catch (Exception e)
{
log.Error("Transmission Failier for ip: " + state.WorkSocket.AddressFamily , e);
}
}
else
{
CloseConnection();
}
}
The application blocks on a concurrent QUEUE with messages to send, And when it successfully dequeues a message it loops through all the registered (Clients) and sends this message to them.
Am I using the begin-send Incorrectly?
One thing I though of, is the fact that its being async, might my program loop through the entire queue and offload it all into the async system buffer?
{EDIT}
private void SendCallback(IAsyncResult asyncResult)
{
try
{
Socket handler = (Socket)asyncResult.AsyncState;
int bytesSent = handler.EndSend(asyncResult);
if (bytesSent == 0)
{
CloseConnection();
return;
}
}
catch
{
CloseConnection();
}
}
Way I drain the queue
ExponentialBackoff eb = new ExponentialBackoff();
while (run)
{
//Fetch Latest Item
ILogItem logItem;
if (incomingQueue.TryDequeue(out logItem))
{
//Handle the logItem
SendEventToObservers(logItem);
//Reset the exponetial backoff counter
eb.reset();
}
else
{
//Exponential backoff thread sleep
eb.sleep();
}
}
private void SendEventToObservers(ILogItem item)
{
foreach (var observer in registeredObservers.ToList())
{
if (observer != null)
{
observer.OnMessageRecieveEvent(new ObserverEvent(item));
// This just calls private void SendSignal(Byte[] signal)
}
}
}
For each queue item you issue an asynchronous send. This means that an unbounded number of send operations might be pending. Resource usage is unbounded. Usually, you'd issue a send and only issue the next after the previous one has completed.
With async IO this is not that easy to do. Either switch to using await (which turns it back into an easy problem) or just use synchronous IO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With