Got at least one data fetching method working; turns out, we can't use a patched LogicStack to get the data
This commit is contained in:
101
Vendor/Swan.Lite-3.1.0/Threading/PeriodicTask.cs
vendored
Normal file
101
Vendor/Swan.Lite-3.1.0/Threading/PeriodicTask.cs
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Swan.Logging;
|
||||
|
||||
namespace Swan.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Schedule an action to be periodically executed on the thread pool.
|
||||
/// </summary>
|
||||
public sealed class PeriodicTask : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>The minimum interval between action invocations.</para>
|
||||
/// <para>The value of this field is equal to 100 milliseconds.</para>
|
||||
/// </summary>
|
||||
public static readonly TimeSpan MinInterval = TimeSpan.FromMilliseconds(100);
|
||||
|
||||
private readonly Func<CancellationToken, Task> _action;
|
||||
private readonly CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
private TimeSpan _interval;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PeriodicTask"/> class.
|
||||
/// </summary>
|
||||
/// <param name="interval">The interval between invocations of <paramref name="action"/>.</param>
|
||||
/// <param name="action">The callback to invoke periodically.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel operations.</param>
|
||||
public PeriodicTask(TimeSpan interval, Func<CancellationToken, Task> action, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_action = action ?? throw new ArgumentNullException(nameof(action));
|
||||
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
_interval = ValidateInterval(interval);
|
||||
|
||||
Task.Run(ActionLoop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="PeriodicTask"/> class.
|
||||
/// </summary>
|
||||
~PeriodicTask()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Gets or sets the interval between periodic action invocations.</para>
|
||||
/// <para>Changes to this property take effect after next action invocation.</para>
|
||||
/// </summary>
|
||||
/// <seealso cref="MinInterval"/>
|
||||
public TimeSpan Interval
|
||||
{
|
||||
get => _interval;
|
||||
set => _interval = ValidateInterval(value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeSpan ValidateInterval(TimeSpan value)
|
||||
=> value < MinInterval ? MinInterval : value;
|
||||
|
||||
private async Task ActionLoop()
|
||||
{
|
||||
for (; ; )
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(Interval, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
await _action(_cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException) when (_cancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (TaskCanceledException) when (_cancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Log(nameof(PeriodicTask));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user