Проблема с памятью с асинхронным сокетом и начало отправки

Сегодня я заметил, что мое одно приложение, которое я разрабатываю, серьезно растет в памяти. Поэтому я сделал профиль памяти Visual Studio и нашел следующие результаты:

 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

Это было сверх использования памяти с ~ 600 МБ.

Мне это не кажется правильным, и я не уверен, почему это так?

Вот моя функция отправки:

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();
        }
    }

Приложение блокируется в параллельной очереди с сообщениями для отправки, и когда оно успешно удаляет сообщение из очереди, оно проходит через всех зарегистрированных (клиентов) и отправляет им это сообщение.

Я неправильно использую начало отправки?

Одна вещь, о которой я думаю, это тот факт, что она асинхронная, может ли моя программа перебрать всю очередь и выгрузить ее в асинхронный системный буфер?

{РЕДАКТИРОВАТЬ}

private void SendCallback(IAsyncResult asyncResult)
    {
        try
        {
            Socket handler = (Socket)asyncResult.AsyncState;
            int bytesSent = handler.EndSend(asyncResult);
            if (bytesSent == 0)
            {
                CloseConnection();
                return;
            }
        }
        catch
        {
            CloseConnection();
        }
    }

Как я сливаю очередь

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)
            }
        }
    }

person Zapnologica    schedule 17.07.2014    source источник
comment
Опубликуйте обратный вызов и то, как вы истощаете очередь.   -  person usr    schedule 17.07.2014
comment
@usr Готово :) Надеюсь, это поможет   -  person Zapnologica    schedule 17.07.2014


Ответы (1)


Для каждого элемента очереди вы выполняете асинхронную отправку. Это означает, что может ожидаться неограниченное количество операций отправки. Использование ресурсов не ограничено. Обычно вы запускаете отправку и отправляете следующую только после завершения предыдущей.

С асинхронным вводом-выводом это сделать не так просто. Либо переключитесь на использование await (что превращает его обратно в простую проблему), либо просто используйте синхронный ввод-вывод.

person usr    schedule 17.07.2014
comment
Итак, моя проблема в том, что я разгружаю свою очередь в ожидающую асинхронность? - person Zapnologica; 17.07.2014
comment
да. ____________________________ - person usr; 17.07.2014