Home > Back-end >  How to run 10 long-running functions repeatedly at specific times, avoiding overlapping execution?
How to run 10 long-running functions repeatedly at specific times, avoiding overlapping execution?

Time:10-05

I am creating a .NET core worker service that is intended to run 10 different long running functions which parse various CSV files and spreadsheets.

I need each function to run at various times daily based on the specific function. If the very same function is currently running then it must 'await' that same function to finish before a new run.

I am new to async/await. Could anyone suggest an approach that would allow all 10 functions to run in parallel but never the same function at once?

Thanks in advance!

EDIT:

  • These parsers take anywhere from 5 minutes to 5 hrs to run.

  • Each function has its own unique needs of when exactly when to run daily or even hourly.

  • If a current function is running and the same function is up to run again, the next function should be removed until the next scheduled time and repeat if needed

CodePudding user response:

While I use "await/async" a lot it does not mean I use them always. In such case I would use timers (with single trigger, non-repeating), and at the end of each function (or wrapper for it) I would set timer again. This guarantees that execution will not overlap.

CodePudding user response:

Curious about thoughts on this approach.

Worker class:

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            //If(NOT SCHEDULED TIME RETURN) //QUARTZ JOB SCHEDULING HERE???

            _tasksManager.LongProccess1Async(stoppingToken);
             _tasksManager.LongProccess2Async(stoppingToken);
            await Task.Delay(_intDelay, stoppingToken); //1 * 1000 = 1 second
        }
    }

Task Manager Class:

private Task<long>? _taskLongProccess1;
    //private long _taskParseDelimitedFiles;
    public async Task longProccess1Async(CancellationToken stoppingToken)
    {

        var pc = _parserConfigs.Find(p => p.Name == "longProccess1");

        while (!stoppingToken.IsCancellationRequested)
        {
            if (_taskLongProccess1 == null)
                _taskLongProccess1 = Task.Run(() => _delimitedParser.LongProccess1(pc.FilePath, pc.Delimiter, pc.ConnectionString, pc.Schema, pc.BulkSize));

            if (_taskLongProccess1.Status == TaskStatus.Running)
            {
                await Task.Delay(pc.Delay, stoppingToken);
            }
            else if (_taskLongProccess1.Status == TaskStatus.RanToCompletion)
            {

                //ONCE DONE LOG AND NULL TASK
                LoggingFunctions.addToLog(_logger, $"Total execution time for task:LongProccess1 = {_taskLongProccess1}", LoggingHelpers.InformationCode);
                _taskLongProccess1 = null;
            }

        }
    }


    private Task<long>? _taskLongProccess2;
    //private long _taskParseDelimitedFiles;
    public async Task longProccess2Async(CancellationToken stoppingToken)
    {

        var pc = _parserConfigs.Find(p => p.Name == "longProccess2");

        while (!stoppingToken.IsCancellationRequested)
        {
            if (_taskLongProccess2 == null)
                _taskLongProccess2 = Task.Run(() => _delimitedParser.LongProccess2(pc.FilePath, pc.Delimiter, pc.ConnectionString, pc.Schema, pc.BulkSize));

            if (_taskLongProccess2.Status == TaskStatus.Running)
            {
                await Task.Delay(pc.Delay, stoppingToken);
            }
            else if (_taskLongProccess2.Status == TaskStatus.RanToCompletion)
            {

                //ONCE DONE LOG AND NULL TASK
                LoggingFunctions.addToLog(_logger, $"Total execution time for task:LongProccess1 = {_taskLongProccess2}", LoggingHelpers.InformationCode);
                _taskLongProccess2 = null;
            }

        }
    }
  • Related