Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Task cancellation when using System.Timers

I'm unsure how best to cancel a task that is running a system timer. In the code below, every 60 mins the timer will elapse and then run another method (CheckFileOverflow) that is used to check the file size of a system log txt. file

Cancellation of the timer ideally would be done by a button click or another method that calls the cancellation. The timer will effectively be allowed to run for as long as the software is running, but when the user eventually shuts down the software i'd like to be able to cancel the task in a responsible fashion i.e. not run the risk of ongoing thread pool resources lingering being used in the background.

I have spent many many hours reading up on cancellation tokens but still don't get it :(

public void SystemEventLoggerTimer()
    {
        SysEvntLogFileChckTimerRun = true;

        Task.Run(() =>
        {
            System.Timers.Timer timer = new System.Timers.Timer
            { Interval = 1000 * 60 * 60 };
            timer.Elapsed += new ElapsedEventHandler(CheckFileOverflow);
            timer.Start();
        });
    }
like image 662
OJB1 Avatar asked Oct 26 '25 04:10

OJB1


2 Answers

I'd suggest that you use Microsoft's Reactive Framework (aka Rx) - just NuGet System.Reactive.

Then you do this:

IDisposable subscription =
    Observable
        .Interval(TimeSpan.FromHours(1.0))
        .Subscribe(_ => CheckFileOverflow());

When you want to cancel the subscription just call subscription.Dispose().

Rx is ideal for abstracting away timers, events, tasks, async operations, etc.

like image 86
Enigmativity Avatar answered Oct 28 '25 16:10

Enigmativity


You can change your method to something like this

  public void SystemEventLoggerTimer(CancellationToken cancelToken)
        {
            SysEvntLogFileChckTimerRun = true;

            Task.Run(async () =>
            {
                // Keep this task alive until it is cancelled
                while (!cancelToken.IsCancellationRequested)
                {
                    await Task.Delay(TimeSpan.FromMinutes(60));
                    CheckFileOverflow();
                }
            });
        }

Then you call SystemEventLoggerTimer like this

var cancelSource = new CancellationTokenSource();
SystemEventLoggerTimer(cancelSource.Token);

you can cancel this Token when program has been disposed or simply at the end of your main function

like image 38
Amir Hossein Esmaill Zade Avatar answered Oct 28 '25 17:10

Amir Hossein Esmaill Zade



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!