2014-07-17 14 views
5

Zauważyłem, że dzisiaj moja rozwijająca się aplikacja znacznie rośnie w pamięci. Więc zrobiłem Visual Studio profilu pamięci i znalazłem następujące wyniki:Problem z pamięcią z gniazdem asynchronicznym i rozpoczęcie wysyłania

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 

To było na górze Wykorzystanie pamięci z ~ 600Meg

to robi wydają się poprawne do mnie i nie jestem pewien, dlaczego go jest tak?

Oto moja wyślij funkcja:

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

Bloki aplikacji na równoczesną Kolejka komunikatów do wysłania, a po pomyślnym dequeues wiadomość zapętla się przez wszystkie zarejestrowane (klienci) i wysyła ten komunikat do im.

Czy używam begin-send niepoprawnie?

Jedną z rzeczy, z których bym był związany jest fakt, że jego asynchronizacja może spowodować, że mój program przejdzie przez całą kolejkę i rozładuje go do bufora systemu asynchronicznego?

{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 opróżnić kolejkę

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

Opublikuj wywołanie zwrotne i sposób drenażu kolejki. – usr

+0

@usr Gotowe :) Mam nadzieję, że pomaga – Zapnologica

Odpowiedz

1

Dla każdego elementu kolejki wydać asynchronicznego wysyłania. Oznacza to, że nieokreślona liczba operacji wysyłania może być w toku. Wykorzystanie zasobów jest nieograniczone. Zwykle wystawiasz wysyłkę i wydajesz tylko następną po zakończeniu poprzedniej.

Nie jest to łatwe z asynchronicznym IO. Przestaw się na używanie oczekującego (co zmienia go z powrotem w łatwy problem) lub po prostu użyj synchronicznego IO.

+0

Więc moim problemem jest to, że jestem odciążenie mojej kolejki do oczekującej asynchronizacji? – Zapnologica

+2

Tak. ______________________________ – usr