Advertisement
MalikDrako

OutOfMemoryException

Jul 18th, 2015
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.25 KB | None | 0 0
  1. // Communication layer
  2. // Handles sending commands on other ports, in addition to what is shown here
  3. public class Communication {
  4.     public delegate void delData(List<byte> data);
  5.    
  6.     private EventDrivenTCPClient dataClient;
  7.    
  8.     private int pendingDataCnt;
  9.     private List<byte> pendingDataRcv = new List<byte>();
  10.     public event delData OnDataRcvd;
  11.    
  12.    
  13.     public void Connect() {
  14.         dataClient = new EventDrivenTCPClient(address, (int)CommonSettings.Default.DataPort, false);
  15.         dataClient.DataEncoding = encoding;
  16.         dataClient.DataReceived += dataClient_DataReceived;
  17.         dataClient.ConnectionStatusChanged += dataClient_ConnectionStatusChanged;
  18.         dataClient.Connect();
  19.     }
  20.    
  21.     void dataClient_DataReceived(EventDrivenTCPClient sender, object data) {
  22.         ReceivePortBytes("Data", 4, false, LogNextData || outputDataConsole, ref pendingDataCnt, ref pendingDataRcv, (byte[])data, RcvData);
  23.     }
  24.    
  25.     // Called after receiving a complete packet
  26.     void RcvData(List<byte> data) {
  27.         if (OnDataRcvd != null) {
  28.             OnDataRcvd(data);
  29.         }
  30.     }
  31.    
  32.     // Store received bytes and determine if a complete packet has been received
  33.     // Reused for multiple sockets
  34.     private bool ReceivePortBytes(string portName, int lengthMult, bool usesUID, bool logHex, ref int pendingCnt, ref List<byte> pendingRcv, byte[] data, delMessage callback = null){
  35.         bool gotFullPacket = false;
  36.         pendingRcv.AddRange(data);
  37.         CheckPendingPort(portName, lengthMult, ref pendingCnt, ref pendingRcv);
  38.         // Loop through any complete packets
  39.         while (pendingCnt > 0 && pendingRcv.Count >= 4 + pendingCnt) {
  40.             gotFullPacket = true;
  41.             List<byte> msg = pendingRcv.GetRange(0, pendingCnt + 4);
  42.             pendingRcv.RemoveRange(0, pendingCnt + 4);
  43.             pendingCnt = 0;
  44.             if (callback != null)
  45.             {
  46.                 callback(msg);
  47.             }
  48.             CheckPendingPort(portName, lengthMult, ref pendingCnt, ref pendingRcv);
  49.         }
  50.         return gotFullPacket;
  51.     }
  52.    
  53.     // Determine # of bytes we are expecting on this socket
  54.     private void CheckPendingPort(string portName, int lengthMult, ref int pendingCnt, ref List<byte> pendingRcv) {
  55.         if (pendingCnt == 0 && pendingRcv.Count >= 4) {
  56.             byte[] cnt = FixEndian(pendingRcv.GetRange(0, 4).ToArray());
  57.             pendingCnt = BitConverter.ToInt32(cnt, 0) * lengthMult;
  58.             Console.WriteLine("Expecting " + pendingCnt + " bytes on " + portName + " port");
  59.         }
  60.     }
  61.    
  62.     private byte[] FixEndian(byte[] arr) {
  63.         if (BitConverter.IsLittleEndian)
  64.             Array.Reverse(arr);
  65.         return arr;
  66.     }
  67. }
  68.  
  69. // Form that handles capturing data
  70. public class DataStorage {
  71.     List<RawData> param1 = new List<RawData>(); // Count = #channels
  72.     List<RawData> param2 = new List<RawData>();
  73.     List<RawData> param3 = new List<RawData>();
  74.    
  75.     int _storedEvents = 0;
  76.     int storedEvents {
  77.         get { return _storedEvents; }
  78.         set {
  79.             _storedEvents = value;
  80.             if (InvokeRequired) {
  81.                 BeginInvoke((MethodInvoker)delegate
  82.                 {
  83.                     // Update a label
  84.                     L_StoredEvents.Text = "Stored Events: " + _storedEvents;
  85.                 });
  86.             } else {
  87.                 L_StoredEvents.Text = "Stored Events: " + _storedEvents;
  88.             }
  89.         }
  90.     }
  91.     int numEvents = 0;
  92.    
  93.     // Hooked up to Communication.OnDataRcvd
  94.     public void AddData(List<byte> data){
  95.  
  96.         int count = BitConverter.ToInt32(FixEndian(data.GetRange(0, 4).ToArray()), 0);
  97.         int idx = 1;
  98.         try {
  99.             while (idx < count) {
  100.                 float timestamp = BitConverter.ToSingle(FixEndian(data.GetRange(idx++ * 4, 4).ToArray()), 0);
  101.                 timestamps.Add(timestamp);
  102.                 for (int i = 0; i < channels; i++) {
  103.                     if (useParam1) {
  104.                         float p1 = BitConverter.ToSingle(FixEndian(data.GetRange(idx++ * 4, 4).ToArray()), 0);
  105.                         param1[i].data.Add(p1);
  106.                     }
  107.                     if (useParam2) {
  108.                         float p2 = BitConverter.ToSingle(FixEndian(data.GetRange(idx++ * 4, 4).ToArray()), 0);
  109.                         param2[i].data.Add(p1);
  110.                     }
  111.                     if (useParam3) {
  112.                         float p3 = BitConverter.ToSingle(FixEndian(data.GetRange(idx++ * 4, 4).ToArray()), 0);
  113.                         param3[i].data.Add(p3);
  114.                     }
  115.                 }
  116.                 storedEvents++;
  117.                 numEvents++;
  118.             }
  119.             if (limitedCapture) {
  120.                 BeginInvoke((MethodInvoker)delegate {
  121.                     // Update ProgressBar
  122.                     PB_CaptureProgress.Value = (numEvents < PB_CaptureProgress.Maximum ? numEvents : PB_CaptureProgress.Maximum);
  123.                 });
  124.                 if (numEvents >= Settings.Default.NSamplesToCapture) {
  125.                     StopCapture();
  126.                     MessageBox.Show("Finished capturing " + numEvents + " events", "Finished Capturing", MessageBoxButtons.OK);
  127.                 }
  128.             }
  129.         }
  130.         catch (ArgumentException e) {
  131.             terminal.AppendError("Error parsing data");
  132.             Console.WriteLine(e.Message + "\n" + e.StackTrace);
  133.         }
  134.         catch (OutOfMemoryException) {
  135.             // After switching to ChunkedList instead of List<float> in RawData, I get OOM exceptions in other areas
  136.             terminal.AppendError("Memory limit exceeded, please save and clear data");
  137.         }
  138.     }
  139. }
  140.  
  141. public class RawData {
  142.     public string name;
  143.     public ChunkedList data;
  144. }
  145.  
  146. //ChunkedList from Aloraman
  147. public class ChunkedList {
  148.     private readonly List<float[]> _chunks = new List<float[]>();
  149.     private const int ChunkSize = 8000;
  150.     private int _count = 0;
  151.  
  152.     public int Count {
  153.         get { return _count; }
  154.     }
  155.  
  156.     public void Add(float item) {
  157.         int chunk = _count / ChunkSize;
  158.         int ind = _count % ChunkSize;
  159.         if (ind == 0)
  160.         {
  161.             _chunks.Add(new float[ChunkSize]);
  162.         }
  163.         _chunks[chunk][ind] = item;
  164.         _count++;
  165.     }
  166.  
  167.     public float this[int index] {
  168.         get {
  169.             if (index < 0 || index >= _count) throw new IndexOutOfRangeException();
  170.             int chunk = index / ChunkSize;
  171.             int ind = index % ChunkSize;
  172.             return _chunks[chunk][ind];
  173.         }
  174.         set {
  175.             if (index < 0 || index >= _count) throw new IndexOutOfRangeException();
  176.             int chunk = index / ChunkSize;
  177.             int ind = index % ChunkSize;
  178.             _chunks[chunk][ind] = value;
  179.         }
  180.     }
  181.  
  182.     public void Clear() {
  183.         _chunks.Clear();
  184.         _count = 0;
  185.         // anything else i need to do to properly clear?
  186.     }
  187. }
  188.  
  189. // EventDrivenTCPClient from https://www.daniweb.com/software-development/csharp/code/422291/user-friendly-asynchronous-event-driven-tcp-client with this modification
  190. public class EventDrivenTCPClient {
  191.  
  192.     private void cbDataReceived(IAsyncResult result) {
  193.         var sock = result.AsyncState as Socket;
  194.  
  195.         if (sock == null)
  196.             throw new InvalidOperationException("Invalid IASyncResult - Could not interpret as a socket");
  197.         SocketError err = new SocketError();
  198.         try {
  199.             int bytes = sock.EndReceive(result, out err);
  200.             if (bytes == 0 || err != SocketError.Success) {
  201.                 lock (SyncLock) {
  202.                     tmrReceiveTimeout.Start();
  203.                     return;
  204.                 }
  205.             } else {
  206.                 lock (SyncLock) {
  207.                     tmrReceiveTimeout.Stop();
  208.                 }
  209.             }
  210.             if (DataReceived != null) {
  211. //                    DataReceived.BeginInvoke(this, _encode.GetString(dataBuffer, 0, bytes), new AsyncCallback(cbDataRecievedCallbackComplete), this);
  212.                 byte[] rcv = new byte[bytes];
  213.                 Array.Copy(dataBuffer, rcv, bytes);
  214.                 DataReceived.BeginInvoke(this, rcv, new AsyncCallback(cbDataRecievedCallbackComplete), this);
  215.             }
  216.         } catch (ObjectDisposedException) {
  217.             Console.WriteLine("TCP Client closed");
  218.         }
  219.     }
  220. }
  221.  
  222. // Form to display the data, not used during this test
  223. public class DataDisplay {
  224.  
  225.     // Hooked up to Communication.OnDataRcvd
  226.     public void AddData(List<byte> data) { // false
  227.         if (!Settings.Default.UseHistogram)
  228.             return;
  229.         }
  230.        
  231.         // Parse data and add into individual circular buffer ( float[10000] )
  232.     }
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement