diff --git a/RGB.NET.Core/RGB.NET.Core.csproj b/RGB.NET.Core/RGB.NET.Core.csproj
index f3dad45..db842ba 100644
--- a/RGB.NET.Core/RGB.NET.Core.csproj
+++ b/RGB.NET.Core/RGB.NET.Core.csproj
@@ -75,6 +75,8 @@
+
+
diff --git a/RGB.NET.Core/RGBSurfaceUpdater.cs b/RGB.NET.Core/RGBSurfaceUpdater.cs
new file mode 100644
index 0000000..c040acc
--- /dev/null
+++ b/RGB.NET.Core/RGBSurfaceUpdater.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace RGB.NET.Core
+{
+ public static partial class RGBSurface
+ {
+ #region Properties & Fields
+
+ private static CancellationTokenSource _updateTokenSource;
+ private static CancellationToken _updateToken;
+ private static Task _updateTask;
+
+ ///
+ /// Gets or sets the update-frequency in seconds. (Calculate by using '1.0 / updates per second')
+ ///
+ public static double UpdateFrequency { get; set; } = 1.0 / 30.0;
+
+ private static UpdateMode _updateMode = UpdateMode.Manual;
+ ///
+ /// Gets or sets the update-mode.
+ ///
+ public static UpdateMode UpdateMode
+ {
+ get { return _updateMode; }
+ set
+ {
+ _updateMode = value;
+ CheckUpdateLoop();
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Checks if automatic updates should occur and starts/stops the update-loop if needed.
+ ///
+ /// Thrown if the requested update-mode is not available.
+ private static async void CheckUpdateLoop()
+ {
+ bool shouldRun;
+ switch (UpdateMode)
+ {
+ case UpdateMode.Manual:
+ shouldRun = false;
+ break;
+ case UpdateMode.Continuous:
+ shouldRun = true;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (shouldRun && (_updateTask == null)) // Start task
+ {
+ _updateTokenSource?.Dispose();
+ _updateTokenSource = new CancellationTokenSource();
+ _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token));
+ }
+ else if (!shouldRun && (_updateTask != null)) // Stop task
+ {
+ _updateTokenSource.Cancel();
+ await _updateTask;
+ _updateTask.Dispose();
+ _updateTask = null;
+ }
+ }
+
+ private static void UpdateLoop()
+ {
+ while (!_updateToken.IsCancellationRequested)
+ {
+ long preUpdateTicks = DateTime.Now.Ticks;
+
+ foreach (IRGBDevice device in _devices)
+ device.Update();
+
+ int sleep = (int)((UpdateFrequency * 1000.0) - ((DateTime.Now.Ticks - preUpdateTicks) / 10000.0));
+ if (sleep > 0)
+ Thread.Sleep(sleep);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/UpdateMode.cs b/RGB.NET.Core/UpdateMode.cs
new file mode 100644
index 0000000..960a03b
--- /dev/null
+++ b/RGB.NET.Core/UpdateMode.cs
@@ -0,0 +1,18 @@
+namespace RGB.NET.Core
+{
+ ///
+ /// Contains list of available update modes.
+ ///
+ public enum UpdateMode
+ {
+ ///
+ /// The will not perform automatic updates. Updates will only occur if is called.
+ ///
+ Manual,
+
+ ///
+ /// The will perform automatic updates at the rate set in .
+ ///
+ Continuous
+ }
+}