Browse Source

Merge pull request #1196 from kekekeks/timer-priority

Fixed DispatcherTimer's priorities
visual-extensions-fallback
Nikita Tsukanov 9 years ago
committed by GitHub
parent
commit
a06631f1a9
  1. 2
      src/Android/Avalonia.Android/AndroidThreadingInterface.cs
  2. 3
      src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs
  3. 13
      src/Avalonia.Base/Threading/Dispatcher.cs
  4. 18
      src/Avalonia.Base/Threading/DispatcherTimer.cs
  5. 6
      src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
  6. 6
      src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs
  7. 4
      src/Linux/Avalonia.LinuxFramebuffer/PlatformThreadingInterface.cs
  8. 2
      src/OSX/Avalonia.MonoMac/PlatformThreadingInterface.cs
  9. 2
      src/Windows/Avalonia.Win32/Win32Platform.cs
  10. 2
      src/iOS/Avalonia.iOS/PlatformThreadingInterface.cs
  11. 2
      tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Threading.cs
  12. 2
      tests/Avalonia.RenderTests/TestBase.cs

2
src/Android/Avalonia.Android/AndroidThreadingInterface.cs

@ -30,7 +30,7 @@ namespace Avalonia.Android
return;
}
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
if (interval.TotalMilliseconds < 10)
interval = TimeSpan.FromMilliseconds(10);

3
src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs

@ -17,10 +17,11 @@ namespace Avalonia.Platform
/// <summary>
/// Starts a timer.
/// </summary>
/// <param name="priority"></param>
/// <param name="interval">The interval.</param>
/// <param name="tick">The action to call on each tick.</param>
/// <returns>An <see cref="IDisposable"/> used to stop the timer.</returns>
IDisposable StartTimer(TimeSpan interval, Action tick);
IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick);
void Signal(DispatcherPriority priority);

13
src/Avalonia.Base/Threading/Dispatcher.cs

@ -84,6 +84,19 @@ namespace Avalonia.Threading
_jobRunner?.Post(action, priority);
}
/// <summary>
/// This is needed for platform backends that don't have internal priority system (e. g. win32)
/// To ensure that there are no jobs with higher priority
/// </summary>
/// <param name="currentPriority"></param>
internal void EnsurePriority(DispatcherPriority currentPriority)
{
if (currentPriority == DispatcherPriority.MaxValue)
return;
currentPriority += 1;
_jobRunner.RunJobs(currentPriority);
}
/// <summary>
/// Allows unit tests to change the platform threading interface.
/// </summary>

18
src/Avalonia.Base/Threading/DispatcherTimer.cs

@ -17,13 +17,11 @@ namespace Avalonia.Threading
private readonly DispatcherPriority _priority;
private TimeSpan _interval;
private readonly Action _raiseTickAction;
/// <summary>
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
/// </summary>
public DispatcherTimer() : this(DispatcherPriority.Normal)
public DispatcherTimer() : this(DispatcherPriority.Background)
{
}
@ -34,7 +32,6 @@ namespace Avalonia.Threading
public DispatcherTimer(DispatcherPriority priority)
{
_priority = priority;
_raiseTickAction = RaiseTick;
}
/// <summary>
@ -187,7 +184,7 @@ namespace Avalonia.Threading
throw new Exception("Could not start timer: IPlatformThreadingInterface is not registered.");
}
_timer = threading.StartTimer(Interval, InternalTick);
_timer = threading.StartTimer(_priority, Interval, InternalTick);
}
}
@ -210,14 +207,7 @@ namespace Avalonia.Threading
/// </summary>
private void InternalTick()
{
Dispatcher.UIThread.InvokeAsync(_raiseTickAction, _priority);
}
/// <summary>
/// Raises the <see cref="Tick"/> event.
/// </summary>
private void RaiseTick()
{
Dispatcher.UIThread.EnsurePriority(_priority);
Tick?.Invoke(this, EventArgs.Empty);
}
}

6
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@ -70,15 +70,13 @@ namespace Avalonia.Gtk3
Native.GtkMainIteration();
}
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
var msec = interval.TotalMilliseconds;
if (msec <= 0)
throw new ArgumentException("Don't know how to create a timer with zero or negative interval");
var imsec = (uint) msec;
if (imsec == 0)
imsec = 1;
return GlibTimeout.StarTimer(imsec, tick);
return GlibTimeout.StartTimer(GlibPriority.FromDispatcherPriority(priority), imsec, tick);
}
private bool[] _signaled = new bool[(int) DispatcherPriority.MaxValue + 1];

6
src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs

@ -48,12 +48,10 @@ namespace Avalonia.Gtk3.Interop
}
}
public static IDisposable StarTimer(uint interval, Action tick)
public static IDisposable StartTimer(int priority, uint interval, Action tick)
{
if (interval == 0)
throw new ArgumentException("Don't know how to create a timer with zero or negative interval");
var timer = new Timer ();
GlibTimeout.Add(GlibPriority.FromDispatcherPriority(DispatcherPriority.Normal), interval,
GlibTimeout.Add(priority, interval,
() =>
{
if (timer.Stopped)

4
src/Linux/Avalonia.LinuxFramebuffer/PlatformThreadingInterface.cs

@ -17,7 +17,7 @@ namespace Avalonia.LinuxFramebuffer
public PlatformThreadingInterface()
{
TlsCurrentThreadIsLoopThread = true;
StartTimer(new TimeSpan(0, 0, 0, 0, 66), () => Tick?.Invoke(this, new EventArgs()));
StartTimer(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 66), () => Tick?.Invoke(this, new EventArgs()));
}
private readonly AutoResetEvent _signaled = new AutoResetEvent(false);
@ -74,7 +74,7 @@ namespace Avalonia.LinuxFramebuffer
}
}
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
return new WatTimer(new System.Threading.Timer(delegate
{

2
src/OSX/Avalonia.MonoMac/PlatformThreadingInterface.cs

@ -16,7 +16,7 @@ namespace Avalonia.MonoMac
public event Action<DispatcherPriority?> Signaled;
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
=> NSTimer.CreateRepeatingScheduledTimer(interval, () => tick());
public void Signal(DispatcherPriority prio)

2
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -114,7 +114,7 @@ namespace Avalonia.Win32
}
}
public IDisposable StartTimer(TimeSpan interval, Action callback)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action callback)
{
UnmanagedMethods.TimerProc timerDelegate =
(hWnd, uMsg, nIDEvent, dwTime) => callback();

2
src/iOS/Avalonia.iOS/PlatformThreadingInterface.cs

@ -51,7 +51,7 @@ namespace Avalonia.iOS
}
}*/
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
=> NSTimer.CreateRepeatingScheduledTimer(interval, _ => tick());
public void Signal(DispatcherPriority prio)

2
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Threading.cs

@ -160,7 +160,7 @@ namespace Avalonia.Base.UnitTests
throw new NotImplementedException();
}
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
throw new NotImplementedException();
}

2
tests/Avalonia.RenderTests/TestBase.cs

@ -161,7 +161,7 @@ namespace Avalonia.Direct2D1.RenderTests
throw new NotImplementedException();
}
public IDisposable StartTimer(TimeSpan interval, Action tick)
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
throw new NotImplementedException();
}

Loading…
Cancel
Save