몇 시스템 개발 시, task 실행을 일정한 시간을 두고 해야할 때가 있다. C#은 .NET 6에서 소개된 PeriodicTimer class를 제공한다.
기능과 사용법을 살펴보고 간단히 구현해보자.
C#에서 PeriodicTimer Class 작동법
1. 필요한 변수를 정의하자.
private readonly PeriodicTimer _periodicTimer;
private readonly CancellationTokenSource _cancellationToken = new();
private Task? _task;
private int _size;
차후 초기화할 PeriodicTimer 변수가 있다. 반복 Task를 종료시킬때 사용할 CancellationTokenSource 변수를 정의하고 초기화했다. random number의 배열을 생성하고 _size 변수가 elements의 수를 갖는다.
2. _periodicTimer, _size를 초기화할 constructor를 만든다.
public PeriodicTimerMethods(TimeSpan timeSpan, int size)
{
_periodicTimer = new PeriodicTimer(timeSpan);
_size = size;
}
3. 우리가 원하는 시간에 random array를 생성하는 task를 실행하는 함수를 만든다.
public static int[] CreateRandomArray(int size)
{
var array = new int[size];
for (int i = 0; i < size; i++)
{
array[i] = Random.Shared.Next();
}
return array;
}
이 함수는 주어진 size의 random 숫자 배열을 반환한다.
4. CreateRandomArray()함수를 호출하고 PeriodicTimer를 초기화하는 함수를 구현한다.
private async Task RandomArrayTimerAsync()
{
try
{
var stopWatch = System.Diagnostics.Stopwatch.StartNew();
var numberOfArrays = 1;
while (await _periodicTimer.WaitForNextTickAsync(_cancellationToken.Token))
{
var array = CreateRandomArray(_size);
foreach (var item in array)
{
Console.WriteLine(item);
}
Console.WriteLine($"Created {numberOfArrays++} arrays in {stopWatch.Elapsed.Seconds}s");
Console.WriteLine(DateTime.Now.ToString("O"));
}
}
catch(OperationCanceledException)
{
}
}
WaitForNextTickAsync() 함수는 timer의 next tick이나 종료시까지 대기한다. 함수 실행 시, 몇 초가 소요되는지 print하기 위해 Stopwatch instance도 생성했다.
5. task의 초기화 종료를 위한 helper methods를 생성한다.
public void Start()
{
_task = RandomArrayTimerAsync();
}
public async Task StopTaskAsync()
{
if (_task is null)
{
return;
}
_cancellationToken.Cancel();
await _task;
_cancellationToken.Dispose();
Console.WriteLine("The array task was canceled");
}
StopTaskAsync() 함수에서 IsCancellationRequested property를 true로 set 하는 Cancel() 함수를 호출한다. resources를 해제하도록 object를 dispose하기 전에 task를 마무리하도록 밀린작업실행을 허용한다.
6. main program에서 적상동작을 확인하자.
Console.WriteLine("Enter array size");
var numOfElements = Convert.ToInt32(Console.ReadLine());
var timerTask = new PeriodicTimerMethods(TimeSpan.FromSeconds(1), numOfElements);
timerTask.Start();
Console.WriteLine("Press any button to terminate the task");
Console.ReadKey();
await timerTask.StopTaskAsync();
output을 보면 1초 간격으로 random arrays가 3개씩 발생하는 것을 볼 수 있다.
위 버전은 Program.Main style이고 아래는 top-level statement 이다.
둘다 동일하게 동작한다.
왜 PeriodicTimer를 사용해야 하는가?
1. 구현하기 쉽다.
2. timing이 정밀하다. 다른 timing mechanisms보다 성공적인 실행 사이에 정확한 시간차를 관리할 수 있다.
3. cancellation이 중요할때 사용할 수 있다. 예를들어, 동작을 완료하기 전에 timer를 취소해야 하는 경우에 그렇다.
C#의 다른 Timer
PeriodicTimer class외에 .NET에 event 기반의 System.Timers.Timer class가 있다. interval을 설정 후 event를 발생시키고 반복 event의 생성 조건을 제공한다.
System.Threading.Timer도 있다.
System.Windows.Forms.Timer는 Windows Forms appliation에서 사용된다.
Web UI 앱에서 사용하는 System.Web.UI.Timer도 있다.
PeriodicTimer가 다른 classes보다 우수하다.
'C#' 카테고리의 다른 글
C#] 식별자/변수명 네이밍 규칙, convention (0) | 2024.01.12 |
---|---|
C#] Deprecated Method 표시, 미사용 함수 표시 (0) | 2024.01.09 |
C#] Path의 File, Directory 여부 확인 (0) | 2024.01.05 |
C#] System.Linq.Enumerable.Aggregate 함수 (0) | 2023.11.15 |
C#] LINQ - Any(), Exists() 함수 차이 (0) | 2023.11.15 |
댓글