Skip to content

Instantly share code, notes, and snippets.

@Ruffo324
Last active March 11, 2021 01:20
Show Gist options
  • Save Ruffo324/18185851fc0040796b15398c93ebb246 to your computer and use it in GitHub Desktop.
Save Ruffo324/18185851fc0040796b15398c93ebb246 to your computer and use it in GitHub Desktop.
Interval based event handling with reactive.
using System;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Timers;
namespace CoreCon
{
internal class Program
{
private static long _maxBytes;
public static void WriteLine(string msg)
{
var usedBytes = GC.GetTotalMemory(true);
_maxBytes = usedBytes > _maxBytes ? usedBytes : _maxBytes;
Console.WriteLine(msg + $"\t\t | RAM: {usedBytes} bytes, runtimeMax {_maxBytes}");
}
private static void Main()
{
var demoClass = new JustAClass();
for (var i = 0; i < 3; i++)
{
using (demoClass.SampleEventOutputToIntervalTime())
{
Console.ReadLine(); // Just keep it alive...
}
WriteLine($"Stopped.. press key to continue. (memory handle check loop ({i}/3).");
Console.ReadLine(); // Just keep it alive...
}
WriteLine("Stopped.. press key to EXIT.");
Console.ReadLine(); // Just keep it alive...
}
}
internal class JustAClass : IDisposable
{
// 💨💨💨💨 Super fast heavy timer.. new event arg every 3ms 🤯.
private readonly Timer _fakeConsoleAccelerator = new Timer(3);
// no need for the tuple (int invokeNr, ElapsedEventArgs invokeArgs)! just used to count the skipped events.
private readonly Subject<(int invokeNr, ElapsedEventArgs invokeArgs)> _intervalSensorPipe = new Subject<(int, ElapsedEventArgs)>(); // "System.Reactive" nuget needed 🙈
private int _eventInvokedCounter;
public JustAClass()
{
// Setup demo stuff.
_fakeConsoleAccelerator.Start();
_eventInvokedCounter = 0;
// Forward event to subject.
_fakeConsoleAccelerator.Elapsed += (_, args) => _intervalSensorPipe.OnNext((_eventInvokedCounter++, args)); // ⚠️ Don't be lazy, don't forget to cleanup the mess later!
}
public IDisposable SampleEventOutputToIntervalTime()
{
// The fancy shit! 😱 Subscribe to the observableCollection, and ignore everything, except the latest eventArgs every xxxMs.
var xxxMs = TimeSpan.FromMilliseconds(100);
return _intervalSensorPipe
.Sample(xxxMs, TaskPoolScheduler.Default) // 🙌 System.Reactive.Linq.Observable.Sample 🥳
.Subscribe(argsEveryXxxMs =>
{
Program.WriteLine($"Now: {DateTime.UtcNow.TimeOfDay} | no {argsEveryXxxMs.invokeNr} - {argsEveryXxxMs.invokeArgs.SignalTime.TimeOfDay}");
}); // ⚠️ Don't be lazy, don't forget to cleanup the mess later!
}
/// <inheritdoc />
public void Dispose()
{
_fakeConsoleAccelerator.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment