提交 5ed9e54c 编写于 作者: M Martin Zikmund

fix: Adjust DispatcherQueueTimer on Android to match WinUI behavior

The tick is now scheduled if and only if the required conditions are actually met
上级 cef298f4
using System;
using System.Collections.Generic;
using System.Text;
using Android.OS;
using Java.Lang;
using static JetBrains.Annotations.ApiStatus;
#if HAS_UNO_WINUI && IS_UNO_UI_DISPATCHING_PROJECT
namespace Microsoft.UI.Dispatching;
......@@ -21,32 +20,14 @@ partial class DispatcherQueueTimer
_runnable = new TickRunnable(this);
}
private void StartNative(TimeSpan interval)
{
var longInterval = (long)interval.TotalMilliseconds;
_runnable.Interval = longInterval;
_handler.PostDelayed(_runnable, longInterval);
}
private void StartNative(TimeSpan dueTime, TimeSpan interval)
{
_runnable.Interval = (long)interval.TotalMilliseconds;
_handler.PostDelayed(_runnable, (long)dueTime.TotalMilliseconds);
}
private void ScheduleTickNative(TimeSpan dueTime) => _handler.PostDelayed(_runnable, (long)dueTime.TotalMilliseconds);
private void StopNative()
{
_runnable.Interval = -1;
_handler.RemoveCallbacks(_runnable);
}
private void StopNative() => _handler.RemoveCallbacks(_runnable);
private class TickRunnable : Java.Lang.Object, IRunnable
{
private readonly DispatcherQueueTimer _timer;
public long Interval { get; set; }
public TickRunnable(DispatcherQueueTimer timer)
{
_timer = timer;
......@@ -54,16 +35,9 @@ partial class DispatcherQueueTimer
public void Run()
{
var interval = Interval;
if (interval >= 0)
if (_timer.IsRunning)
{
_timer.RaiseTick();
interval = Interval;
if (interval >= 0) // be sure to not self restart if the timer was Stopped by the Tick event handler
{
_timer._handler.PostDelayed(this, interval);
}
}
}
}
......
......@@ -93,7 +93,7 @@ public partial class DispatcherQueueTimer
LastTickElapsed = TimeSpan.Zero;
if (Interlocked.CompareExchange(ref _state, States.Running, States.Idle) == States.Idle)
{
StartNative(Interval);
ScheduleTickNative(Interval);
}
else
{
......@@ -101,7 +101,7 @@ public partial class DispatcherQueueTimer
// https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.dispatchertimer.start#Windows_UI_Xaml_DispatcherTimer_Start
StopNative();
StartNative(Interval);
ScheduleTickNative(Interval);
}
_stopwatch.Restart();
......@@ -138,12 +138,12 @@ public partial class DispatcherQueueTimer
if (IsRunning) // be sure to not self restart if the timer was Stopped by the Tick event handler
{
StartNative(interval);
ScheduleTickNative(interval);
}
}
else
{
StartNative(interval - elapsed, interval);
ScheduleTickNative(interval - elapsed);
}
}
......@@ -181,10 +181,13 @@ public partial class DispatcherQueueTimer
isRunning &&
IsRepeating;
OnTickFinished(shouldContinueTicking);
if (IsRunning && IsRepeating && shouldContinueTicking)
{
ScheduleTickNative(Interval);
}
}
partial void OnTickFinished(bool continueTicking);
partial void ScheduleNextTick();
~DispatcherQueueTimer()
{
......
......@@ -15,14 +15,12 @@ partial class DispatcherQueueTimer
private Timer _timer;
private void StartNative(TimeSpan interval)
private void ScheduleTickNative(TimeSpan interval)
{
_timer ??= new Timer(_ => DispatchRaiseTick());
_timer.Change(ClampInterval(interval), Timeout.InfiniteTimeSpan);
}
private void StartNative(TimeSpan dueTime, TimeSpan interval) => StartNative(dueTime);
private void DispatchRaiseTick()
{
#if __WASM__
......@@ -35,14 +33,6 @@ partial class DispatcherQueueTimer
_ = CoreDispatcher.Main.RunAsync(Uno.UI.Dispatching.CoreDispatcherPriority.Normal, () => RaiseTick());
}
partial void OnTickFinished(bool continueTicking)
{
if (IsRunning && IsRepeating && continueTicking)
{
_timer.Change(ClampInterval(Interval), Timeout.InfiniteTimeSpan);
}
}
private void StopNative()
{
_timer?.Dispose();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册