csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.7 KiB
93 lines
2.7 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Rendering;
|
|
using Avalonia.Threading;
|
|
|
|
namespace Avalonia.Controls.Platform
|
|
{
|
|
public class InternalPlatformThreadingInterface : IPlatformThreadingInterface
|
|
{
|
|
public InternalPlatformThreadingInterface()
|
|
{
|
|
TlsCurrentThreadIsLoopThread = true;
|
|
}
|
|
|
|
private readonly AutoResetEvent _signaled = new AutoResetEvent(false);
|
|
|
|
|
|
public void RunLoop(CancellationToken cancellationToken)
|
|
{
|
|
var handles = new[] { _signaled, cancellationToken.WaitHandle };
|
|
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
{
|
|
Signaled?.Invoke(null);
|
|
WaitHandle.WaitAny(handles);
|
|
}
|
|
}
|
|
|
|
|
|
class TimerImpl : IDisposable
|
|
{
|
|
private readonly DispatcherPriority _priority;
|
|
private readonly TimeSpan _interval;
|
|
private readonly Action _tick;
|
|
private Timer _timer;
|
|
private GCHandle _handle;
|
|
|
|
public TimerImpl(DispatcherPriority priority, TimeSpan interval, Action tick)
|
|
{
|
|
_priority = priority;
|
|
_interval = interval;
|
|
_tick = tick;
|
|
_timer = new Timer(OnTimer, null, interval, TimeSpan.FromMilliseconds(-1));
|
|
_handle = GCHandle.Alloc(_timer);
|
|
}
|
|
|
|
private void OnTimer(object state)
|
|
{
|
|
if (_timer == null)
|
|
return;
|
|
Dispatcher.UIThread.Post(() =>
|
|
{
|
|
|
|
if (_timer == null)
|
|
return;
|
|
_tick();
|
|
_timer?.Change(_interval, TimeSpan.FromMilliseconds(-1));
|
|
});
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
_handle.Free();
|
|
_timer.Dispose();
|
|
_timer = null;
|
|
}
|
|
}
|
|
|
|
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
|
|
{
|
|
return new TimerImpl(priority, interval, tick);
|
|
}
|
|
|
|
public void Signal(DispatcherPriority prio)
|
|
{
|
|
_signaled.Set();
|
|
}
|
|
|
|
[ThreadStatic] private static bool TlsCurrentThreadIsLoopThread;
|
|
|
|
public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread;
|
|
public event Action<DispatcherPriority?> Signaled;
|
|
#pragma warning disable CS0067
|
|
public event Action<TimeSpan> Tick;
|
|
#pragma warning restore CS0067
|
|
|
|
}
|
|
}
|
|
|