samuel guedon
samuel guedon

Reputation: 626

Task status changed to RanToCompletion while stille running

I created a method which handles a few checks before starting a Task passed as a parameter.

My issue is that the task created there do not behave as expected and are quickly considered as RanToCompletion despite code is still running.

Here is an example:

    public Task Main(CancellationToken localToken)
    {
        try
        {
            AddToTasker(new Task(async () => await ExtractAllOffer(localToken), localToken), TaskTypes.Extractor);

            //this allows to extract only the task for the given task type through the list created in AddToTasker, actual code is not necessary the returned array is correct
            Task.WaitAll(GetTasksArray(new TaskTypes[]{TaskTypes.Extractor}), localToken);

            IsRunning = false;
        }
    }

    public void AddToTasker(Task task, TaskTypes taskstype)
    {

        /*
         * Whatever code to perform few check before starting the task
         * among which referencing the task within a list which holds also the taskstype
         */


        task.Start();

    }

    async private Task ExtractAllOffer(CancellationToken localToken)
    {
        // *** Do very long Stuff ***
    }

The ExtractAllOffer method is a loop, with a few moment where i await external code completion. At the first await the Task.WaiAll terminates and it goes to IsRunning = false

I checked this thread but it does not seem to be the same issue as I correctly use an async task and not an async void.

Also, the code use to run properly before I shifted the Task execution within the AddToTasker method. Before I used to do like this AddToTasker(Task.Run(() => ExtractAllOffer(localToken), localToken), TaskTypes.Extractor); but I realized I needed to perform checks before starting the Task and needed to factor the checks within the AddToTasker method (I have many calls to this method).

I kind of understand that there is a flaw in how I declare or start my Task but can't figure what.

Help greatly appreciated

Upvotes: 0

Views: 394

Answers (1)

samuel guedon
samuel guedon

Reputation: 626

Thanks to @pere57 and this other thread I see that the wait only wait until the action that creates the Task finishes... which is quite fast.

I have to declare it as a Task< Task> in order to the unwrap the first Task (the action) to access the inner Task (the actual method that gets executed).

So here it goes :

public Task Main(CancellationToken localToken)
{
    try
    {
        AddToTasker(new Task<Task>(() => ExtractAllOffer(localToken), localToken), TaskTypes.Extractor);

        //this allows to extract only the task for the given task type through the list created in AddToTasker, actual code is not necessary the returned array is correct
        Task.WaitAll(GetTasksArray(new TaskTypes[]{TaskTypes.Extractor}), localToken);

        IsRunning = false;
    }
}

public void AddToTasker(Task<Task> task, TaskTypes taskstype)
{

    /*
     * Whatever code to perform few check before starting the task
     * among which referencing the task within a list which holds also the taskstype
     */

    mylistoftask.Add(task.Unwrap()); //I have now to unwrap the task to add the inner one in my list
    task.Start();

}

async private Task ExtractAllOffer(CancellationToken localToken)
{
    // *** Do very long Stuff ***
}

Upvotes: 1

Related Questions