Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ContinueWith guaranteed to execute?

I've got a bit of code that is acting as a light weight, non-blocking, critical section. I am hoping that no matter what happens with _func and cancellationToken in the Task.Run clause, that the continuation is guaranteed to run such that the Exit statement in its finally block will always execute.

Is it safe to assume that the finally block below, short of catastrophic failure in the process, will be executed with roughly the same guarantees that finally normal operates with?

if (Enter())
{
    Task.Run<T>(_func, cancellationToken)
        .ContinueWith((antecedent) =>
        {
            try
            {
                antecedent.Wait(cancellationToken);
                Interlocked.Exchange<T>(ref _result, antecedent.Result);
            }
            catch (AggregateException e)
            {
                Interlocked.Exchange(ref _exceptions, e);
            }
            catch (OperationCanceledException)
            {
                ResetState();
            }
            catch (Exception e)
            {
                Interlocked.Exchange(ref _exceptions, new AggregateException(e));
            }
            finally
            {
                Exit();
            }
        })
}
like image 341
dkackman Avatar asked Feb 20 '16 00:02

dkackman


People also ask

How does ContinueWith work?

ContinueWith(Action<Task,Object>, Object, TaskScheduler)Creates a continuation that receives caller-supplied state information and executes asynchronously when the target Task completes. The continuation uses a specified scheduler.

What does calling task ContinueWith () do?

Calling ContinueWith allocates another task per operation (it wraps your delegate in a task object) instead of re-using the state machine instance as the continuation. So you're static callback is then wrapped in a ContinuationTask object.

What is a continuation Task C#?

A continuation task (also known just as a continuation) is an asynchronous task that's invoked by another task, known as the antecedent, when the antecedent finishes.

Which code creates a chain of task to be executed after one another?

c# - Run sequence of tasks, one after the other - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.

What is continuewith function in Java?

ContinueWith The ContinueWith function is a method available on the task that allows executing code after the task has finished execution. In simple words it allows continuation. Things to note here is that ContinueWith also returns one Task. That means you can attach ContinueWith one task returned by this method.

What is the use of continuewith () method in threading?

public System.Threading.Tasks. Task ContinueWith ( Action<System.Threading.Tasks.Task, object > continuationAction, object state, System.Threading.Tasks.TaskScheduler scheduler); An action to run when the Task completes. When run, the delegate will be passed the completed task and the caller-supplied state object as arguments.

What happens if the continuation criteria are not met?

If the continuation criteria specified through the continuationOptions parameter are not met, the continuation task will be canceled instead of scheduled. Creates a continuation that receives caller-supplied state information and a cancellation token and that executes asynchronously when the target Task completes. public System.Threading.Tasks.

What is continuewith () method in Salesforce?

ContinueWith(Action<Task,Object>, Object, CancellationToken) ContinueWith(Action<Task,Object>, Object, CancellationToken) ContinueWith(Action<Task,Object>, Object, CancellationToken) Creates a continuation that receives caller-supplied state information and a cancellation token and that executes asynchronously when the target Task completes.


Video Answer


2 Answers

Based on the MSDN documentation:

The returned Task will not be scheduled for execution until the current task has completed, whether it completes due to running to completion successfully, faulting due to an unhandled exception, or exiting out early due to being canceled.

So, unless _func never returns (runs in an infinite loop for example), then the continuation will always run.

And when the continuation runs, the finally block is guaranteed to execute as per the rules of C#.

So the answer is yes (unless of course _func never returns).

like image 70
Yacoub Massad Avatar answered Oct 22 '22 09:10

Yacoub Massad


If the token is canceled before the first task runs, the continuation will not run, and thus the finally will not execute. Tested here with VS 2015: http://pastebin.com/9qmUYnqv

Incidentally, there are some design issues with the code as written -- having tasks modify state is not the best idea; the tasks should return values and whatnot. In this particular case, for a nonblocking critical sections, consider using SemaphoreSlim.

like image 2
Mark Sowul Avatar answered Oct 22 '22 10:10

Mark Sowul