title: C# TCP Server/Client Object Transmission/Serialization/De-Serialization Increasingly Using Memory Help Required
body: <p><strong>First and Foremost,</strong></p>
  
  <h2>Thanks in advance to all who may provide help, criticism, advice.</h2>
  
  <p><strong>Language:</strong> C#</p>
  
  <hr>
  
  <p><strong>Objective:</strong> TCP Server/Client For Image And Object Transmission.</p>
  
  <hr>
  
  <p><strong>Server Scenario:</strong> 
  Server will listen for client connection. </p>
  
  <p>Upon client connection server will receive byte[] data from socket</p>
  
  <p>Server will convert byte[] it into (Type) object.</p>
  
  <p>Server will then use this (Type)Object to update WPF Image Control </p>
  
  <hr>
  
  <p><strong>Client Scenario:</strong> </p>
  
  <p>Client will create object ready for transmission.</p>
  
  <p>Client will converting object to stored byte[].</p>
  
  <p>Client will connect to server and send object via a socket</p>
  
  <hr>
  
  <p><strong>Issue:</strong> </p>
  
  <p>I am unsure why this process is increasing 60-100MB of memory used per second.</p>
  
  <p>I would like to know if Byte[] Chunking would be a worth while solution <em>(if so could you please direct me to a resource or provide a solution)</em></p>
  
  <p>It feels like it is not cleaning up after itself properly or re-using variables.</p>
  
  <hr>
  
  <p><strong>Notes:</strong> </p>
  
  <p>The Bitmap Capture and Convert to Byte[] is working great AFAIK this isn't the issue, but I can post code if problem is not in the code below or if others would benefit.</p>
  
  <p>The ObjecttoByte[] and ByteArrayToObject code works and is slightly modified from other stack overflow posts, like wise I can post it if the problem is not in the code below or if others would benefit.</p>
  
  <hr>
  
  <p><strong>Server Listener Code:</strong> </p>
  
  <pre><code>public void StartServer()
      {
          //-------------------------------------------------------
          // Initialize Variables For Server
          //-------------------------------------------------------   
          int recv;
          byte[] data;
  
          //-------------------------------------------------------
          // Configure Server Listener
          //-------------------------------------------------------   
          IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
          Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
          //-------------------------------------------------------
          // Bind Socket To IPEndpoint And Listen
          //-------------------------------------------------------   
          newsock.Bind(ipep);
          newsock.Listen(10);
  
          //-------------------------------------------------------
          // Accept New Connection
          //-------------------------------------------------------   
          Console.WriteLine("Waiting for a client...");
          Socket client = newsock.Accept();
  
          //-------------------------------------------------------
          // Verify Client Endpoint Connection
          //-------------------------------------------------------   
          IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
          Console.WriteLine("Connected with {0} at port {1}", clientep.Address, clientep.Port);
  
          //-------------------------------------------------------
          // Start Reading From Socket While Client Connected
          //-------------------------------------------------------   
          while (client.Connected)
          {
              data = new byte[500000]; // Create Buffer For Object
  
              recv = client.Receive(data); // Ensure Client Has Sent Data
              if (recv == 0)
                  break;
  
              //-------------------------------------------------------
              // Create Test Object And De-Serialize 
              //-------------------------------------------------------   
              TestObject to = new TestObject(); //Object For Storage
              Console.WriteLine("Server Object Size: " + data.Length); // Check Length For Interest
  
              var dataToObject = ByteArrayToObject(data); // Convert Object Byte[] to Object
              to = (TestObject)dataToObject; // Store Converted Byte[] Object into Typed Object
  
              Console.WriteLine("Server De-Serialized Object from Client."); // Provide Information
              Console.Out.WriteLine("Server TestObject: " + to.testString); // Extract And Notify Object String Data
  
              //-------------------------------------------------------
              // Update Main GUI Image (WPF)
              //-------------------------------------------------------   
              this.Dispatcher.Invoke((Action)(() =&gt;
              {
                  TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap)); // Create Type Converter
                  Bitmap bitmap1 = (Bitmap)tc.ConvertFrom(to.testBmp); // Cast into Bitmap from Byte[] 
                  imgRemoteDisplay.Source = ByteMonImaging.GetBitmapSource(bitmap1); // Display Bitmap  
                  bitmap1 = null;
                  tc = null;
              }));
  
              //-------------------------------------------------------
              // Clean Up
              //-------------------------------------------------------   
              dataToObject = null;
              data = null;
              to = null;
              GC.Collect();
              //-------------------------------------------------------
          }
  
          Console.WriteLine("Disconnected from {0}", clientep.Address);
  
          //-------------------------------------------------------
          // Close Listener
          //-------------------------------------------------------   
          client.Close();
          newsock.Close();
      }
  </code></pre>
  
  <hr>
  
  <p><strong>Client Connection Code:</strong> </p>
  
  <pre><code>public void ConnectClient()
      {
          //-------------------------------------------------------
          // Configure Server Connection
          //-------------------------------------------------------
          IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
          Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  
          //-------------------------------------------------------
          // Establish Connection To Server
          //-------------------------------------------------------
          try
          {
              server.Connect(ipep);
          }
          catch (SocketException e)
          {
              Console.WriteLine("Unable to connect to server.");
              Console.WriteLine(e.ToString());
              return;
          }
  
          //-------------------------------------------------------
          // Start Sending Object To Server While Connected
          //-------------------------------------------------------            
          while(server.Connected)
          {
              TestObject to = new TestObject(); // Create blank object store
  
              to.testString = "TestObject String Here"; // Set Blank Object Test String
              var bmpToSend = ByteMonImaging.CaptureBitmap(); // Set Blank Object Test  Bitmap
              to.testBmp = ByteMonImaging.ImageToByte(bmpToSend); // Convert Bitmap to Byte[]    
  
              var byteArray = ObjectToByteArray(to); // Pack Object into Byte[]
              Console.WriteLine("Client Object Size: " + byteArray.Length); // Curious Byte[] Size
              server.Send(byteArray); // Send Byte[] Object Via TCP
              Console.WriteLine("Client Sent Serialized Object to Server."); // Notify Where We Are At
  
              bmpToSend = null; // Clean Up
              to = null; // Clean Up
              byteArray = null; // Clean Up
              GC.Collect(); // Clean Up (Added for Checks)
          }
  
          //-------------------------------------------------------
          // Close Connection to Socket And Server
          //-------------------------------------------------------      
          Console.WriteLine("Disconnecting from server...");
          server.Shutdown(SocketShutdown.Both);
          server.Close();
      }
  </code></pre>
  
  <hr>
  
  <p><strong>Cause of Memory Consumption Located</strong></p>
  
  <pre><code>//-------------------------------------------------------
              // Update Main GUI Image (WPF)
              //-------------------------------------------------------   
              this.Dispatcher.Invoke((Action)(() =&gt;
              {
                  TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap)); // Create Type Converter
                  Bitmap bitmap1 = (Bitmap)tc.ConvertFrom(to.testBmp); // Cast into Bitmap from Byte[] 
                  imgRemoteDisplay.Source = ByteMonImaging.GetBitmapSource(bitmap1); // Display Bitmap  
                  bitmap1 = null;
                  tc = null;
              }));
  </code></pre>
  
  <hr>
  
  <p><strong>Solution:</strong> The problem was the hBitmap was causing memory leak when invoking. Using the finally clause I was able to use externdll to delete the object.</p>
  
  <pre><code> [DllImport("gdi32")]
      static extern int DeleteObject(IntPtr ipObj);
   public static BitmapSource GetBitmapSource(Bitmap bmp)
      {
          IntPtr hBitmap = bmp.GetHbitmap();
          System.Windows.Media.Imaging.BitmapSource b;
          try
          {                                
               b = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                      hBitmap,
                      IntPtr.Zero,
                      System.Windows.Int32Rect.Empty,
                      System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
          }
          finally
          {
              DeleteObject(hBitmap);
          }
          return b;
      }
  </code></pre>