TimeAverage.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. namespace MatrixIO.IO
  7. {
  8. public class TimeAverage : IDisposable
  9. {
  10. private readonly object _syncObject = new object();
  11. private readonly Timer _timer;
  12. private readonly List<long> _previousCounts = new List<long>(301);
  13. private long _currentCount = 0;
  14. private bool _running = false;
  15. public TimeAverage()
  16. {
  17. _timer = new Timer(new TimerCallback(TimeElapsed), this, Timeout.Infinite, Timeout.Infinite);
  18. }
  19. public void Start()
  20. {
  21. lock (_syncObject)
  22. {
  23. _timer.Change(1000, 1000);
  24. _running = true;
  25. }
  26. }
  27. public void Stop()
  28. {
  29. lock(_syncObject)
  30. {
  31. _timer.Change(Timeout.Infinite, Timeout.Infinite);
  32. _running = false;
  33. }
  34. }
  35. public void TimeElapsed(object state)
  36. {
  37. lock(_syncObject)
  38. {
  39. if (!_running) return;
  40. var lastBytes = _currentCount;
  41. _currentCount = 0;
  42. _previousCounts.Add(lastBytes);
  43. if(_previousCounts.Count > 300)
  44. _previousCounts.RemoveRange(0, _previousCounts.Count - 300);
  45. }
  46. }
  47. public void Add(long number)
  48. {
  49. if (!_running) return;
  50. lock(_syncObject) _currentCount += number;
  51. }
  52. public double GetAverage(int seconds)
  53. {
  54. if (seconds < 1 || seconds > 300) throw new ArgumentException();
  55. lock(_syncObject)
  56. {
  57. return _previousCounts.Count > 0
  58. ? _previousCounts.Skip(Math.Max(0, _previousCounts.Count() - seconds)).Take(seconds).Average()
  59. : 0.0;
  60. }
  61. }
  62. public void Dispose()
  63. {
  64. if (_running) Stop();
  65. _timer.Dispose();
  66. }
  67. }
  68. }