132 lines
3.9 KiB
C#
132 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Reflection;
|
|
using System.Xml.Linq;
|
|
|
|
|
|
|
|
namespace ServerCore;
|
|
|
|
//=============================================================================================
|
|
// 주기적 Task 타이머 클래스 이다.
|
|
//
|
|
// author : kangms
|
|
//
|
|
//=============================================================================================
|
|
|
|
public class PeriodicTaskTimer : IAsyncDisposable
|
|
{
|
|
private readonly string m_name;
|
|
private readonly System.Threading.PeriodicTimer m_timer;
|
|
private readonly Task m_timer_task;
|
|
private readonly CancellationTokenSource m_cts;
|
|
|
|
public delegate Task FnFunction();
|
|
private readonly FnFunction m_fn_alarm_function;
|
|
|
|
public PeriodicTaskTimer(string name, Int32 intervalSec, FnFunction fnAlarmFunction)
|
|
{
|
|
m_name = name;
|
|
m_cts = new CancellationTokenSource();
|
|
|
|
m_timer = new System.Threading.PeriodicTimer(TimeSpan.FromSeconds(intervalSec));
|
|
|
|
m_fn_alarm_function = fnAlarmFunction;
|
|
m_timer_task = handleTimerAsync(m_timer, m_cts.Token);
|
|
}
|
|
|
|
//=============================================================================================
|
|
// CancellationTokenSource 를 외부에서 제어할 때 사용한다.
|
|
//=============================================================================================
|
|
public PeriodicTaskTimer(string name, double intervalMSec, CancellationTokenSource cts, FnFunction fnAlarmFunction)
|
|
{
|
|
m_name = name;
|
|
m_cts = cts;
|
|
|
|
m_timer = new System.Threading.PeriodicTimer(TimeSpan.FromMilliseconds(intervalMSec));
|
|
|
|
m_fn_alarm_function = fnAlarmFunction;
|
|
m_timer_task = handleTimerAsync(m_timer, m_cts.Token);
|
|
}
|
|
|
|
private async Task handleTimerAsync(System.Threading.PeriodicTimer timer, CancellationToken cancel = default)
|
|
{
|
|
try
|
|
{
|
|
while (await timer.WaitForNextTickAsync(cancel))
|
|
{
|
|
await Task.Run(() => m_fn_alarm_function.Invoke());
|
|
}
|
|
}
|
|
catch (OperationCanceledException e)
|
|
{
|
|
var msg = $"PeriodicTaskTimer cancel Operation !!! : exception:{e} - {m_name}";
|
|
Log.getLogger().info(msg);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
var err_msg = $"PeriodicTaskTimer exception !!! : exception:{e} - {m_name}";
|
|
Log.getLogger().error(err_msg);
|
|
}
|
|
}
|
|
|
|
public void cancelTimer() => m_cts.Cancel();
|
|
|
|
//for IAsyncDisposable.DisposeAsync()
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
m_timer.Dispose();
|
|
await m_timer_task;
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public System.Threading.PeriodicTimer getPeriodicTimer() => m_timer;
|
|
|
|
public Task getTask() => m_timer_task;
|
|
}
|
|
|
|
|
|
//=============================================================================================
|
|
// 주기적 Task 타이머 지원 클래스 이다.
|
|
//
|
|
// author : kangms
|
|
//
|
|
//=============================================================================================
|
|
public static class PeriodicTaskHelper
|
|
{
|
|
public static async Task runTask(Func<Task> action, TimeSpan interval, CancellationToken cancellationToken = default)
|
|
{
|
|
using var timer = new PeriodicTimer(interval);
|
|
while (cancellationToken.IsCancellationRequested == false)
|
|
{
|
|
try
|
|
{
|
|
await action();
|
|
await timer.WaitForNextTickAsync(cancellationToken);
|
|
}
|
|
catch (OperationCanceledException e)
|
|
{
|
|
var msg = $"PeriodicTaskHelper cancel Operation !!! : Msg:{e.Message}";
|
|
Log.getLogger().info(msg);
|
|
break;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
var err_msg = $"PeriodicTaskHelper exception !!! : errMsg:{e.Message}";
|
|
Log.getLogger().error(err_msg);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void bindToTasks(this PeriodicTaskTimer taskTimer, List<Task> tasks)
|
|
{
|
|
tasks.Add(taskTimer.getTask());
|
|
}
|
|
}
|
|
|