Discovering dot net tasks

54
Discovering .NET Tasks ! Vincent Grondin General Manager – Solutions Vet a CDMV subsidiary C# MVP .NET Montreal User Group Leader Blog: http://geekswithblogs.net/vincentgrondin

Transcript of Discovering dot net tasks

Page 1: Discovering dot net tasks

Discovering .NET Tasks !Vincent GrondinGeneral Manager – Solutions Vet a CDMV subsidiary

C# MVP

.NET Montreal User Group LeaderBlog: http://geekswithblogs.net/vincentgrondin

Page 2: Discovering dot net tasks

Before we dive into this…

• Who worked with Tasks before?

• Who worked with Task Parallel Library

before?

• Who worked with Async and Await before?

•DEMO-WARE !!!!

Page 3: Discovering dot net tasks

Disclaimer !

Page 4: Discovering dot net tasks

Disclaimer !

Page 5: Discovering dot net tasks

Disclaimer !

Page 6: Discovering dot net tasks

Disclaimer !

Page 7: Discovering dot net tasks

Content

• What are Tasks?

• When should you use Tasks?

• Various kind of Task relationships

• Exception handling in Tasks

• Cancellation handling in Tasks

Page 8: Discovering dot net tasks

What are Tasks?

Page 9: Discovering dot net tasks

• A task is an asynchronous unit of work

• A task is nothing more than a class that wraps a method

• Think of tasks as the evolution of Asynchronous Delegates

• Tasks offer greater control on :

– where should the method be executed (threading)

– what happens when the method has finished executing

– how to handle exceptions in asynchronous scenarios

– how to handle a cancellation in asynchronous scenarios

• They allow for a more « Functional » programming model by

clearly defining a unit of work.

– When this task ends, fails or is canceled, start this task

What are tasks?

Page 10: Discovering dot net tasks

• You can wait for a task to complete but it’s not a must!

• Task execute void returning methods. (Action)

• Task<TResult> execute methods that return TResult

– Example : You want to convert a method to a task…

• Suppose that your method returns a Bool

• The Task based equivalent of this method would be a Task<Bool>

• Wrap a task around your method

• Task<Bool> myTask = new Task(() =>

{

return this.MyBoolReturningMethod() ;

});

What are tasks?

Page 11: Discovering dot net tasks

• Waiting for a task means…

– the thread that calls “.Wait();” on the task is blocked

– the code execution in this method stops at the “.Wait();” line.

– when the task finishes, the next statement is right after the “.Wait();”.

• Awaiting a task means…

– the current thread is free to process other pieces of code

– the code execution in this method stops at the “await point”.

– the rest of the method after the “await point” is put into a “callback”

– the code resumes after the method call in the parent method

– when the task finishes, the next statement is right after the “await

point”

• …with await also comes other pains…

What are Tasks – Wait vs Await

Page 12: Discovering dot net tasks

What are Tasks? – Demo 1 & 2

Page 13: Discovering dot net tasks

What are Tasks? – Demo 3

Page 14: Discovering dot net tasks

Disclaimer !

Page 15: Discovering dot net tasks

When should you use Tasks?

Page 16: Discovering dot net tasks

When should you use Tasks?

• Any time you want to do something

asynchronously.

• When you need to communicate with a

service

Page 17: Discovering dot net tasks

When should you use Tasks? – Demo 4

Page 18: Discovering dot net tasks

Various kind of Task relationships

Why does the relationship type matters?

Parent-AttachedChild relationship

Parent-DetachedChild relationship

Antecedent-Continuation relationship

Page 19: Discovering dot net tasks

Why does the relationship type matters?

• Tasks can relate one to another and this relationship has

serious implications over the following :

– Should a Task wait for another to complete before joining back to the

calling thread?

– How will exceptions be propagated between tasks in a relationship?

– Will the status of a task affect the status of another task in a

relationship?

• It all depends on the TYPE of relationship used

Page 20: Discovering dot net tasks

Parent-AttachedChild relationship

• The parent Task starts another Task inside itself and

explicitly attaches it as its child.

• Use “TaskCreationOptions.AttachedToParent” when

creating the child Task.

• A parent Task can have many attached children

• The parent Task will wait for all children to complete (faulted-canceled-completed)

• Exceptions will be propagated from a child to its parent.

• The parent Task status depends on the status of it’s

children.

Page 21: Discovering dot net tasks

Parent-AttachedChild relationship

Task 1 (parent)

Task 2(child)

Task 3(child)

Task 4(child)

2

3

4

Main thread

1

Page 22: Discovering dot net tasks

Parent-DetachedChild relationship

• The parent Task starts another Task inside itself.

• A parent Task can have many detached and / or attached

children

• The parent Task won’t wait for detached children to

complete (faulted-canceled-completed)

• Exceptions won’t be propagated from a child to its parent.

• The parent Task status doesn’t depend on the status of its

children.

Page 23: Discovering dot net tasks

Parent-DetachedChild relationship

Task 1 (parent)

Task 2(child)

Task 3(child)

Task 4(child)

2

3

4

Main thread

1

Page 24: Discovering dot net tasks

Antecedent-Continuation relationship

• Happens when you define a Task using the “ContinueWith”

command on a Task.

– The first Task is the Antecedent

– The second Task is the Continuation and receives the Antecedent

Task as a parameter so it can use it in it’s own Task.

• Continuation Tasks won’t run until the parent and all it’s

attached children Tasks complete (faulted-canceled-completed)

• Exceptions won’t propagate to the Antecedent Task

• The status of the Continuation Task won’t affect the status of

the Antecedent Task

• Continuation Tasks are a great way to handle exceptions on

Antecedents Tasks!

Page 25: Discovering dot net tasks

• Chaining Tasks one after the other in a “Antecedent-

Continuation” relationship…

MainTask

Error Handling

Error Handling &

Continuation of the

workflow

Antecedent-Continuation relationship

Page 26: Discovering dot net tasks

• Another form of Antecedent-Continuation relationship is what I call a “Forked

Continuation” relationship

• Use the TaskContinuationOptions on your Continuation Task to specify which

Task to use when

MainTask

Error Handling

Continuation of the

workflow

Cancel

OnlyOnRanToCompletion

Antecedent-Continuation relationship

Page 27: Discovering dot net tasks

Antecedent-Continuation relationship – Demo 5

Page 28: Discovering dot net tasks

Disclaimer

Page 29: Discovering dot net tasks

• If you write a Task that has a Continuation Task attached to it, make sure you wait

for the right Task otherwise…. you’re in for surprises !

task.Wait()

Pitfalls

Page 30: Discovering dot net tasks

How to handle exceptions?

Facts about exceptions in Tasks

What’s the Observed Task concept?

Pitfalls

Page 31: Discovering dot net tasks

• A Task that throws an unhandled exception will add the exception to a list

of exceptions inside an AggregateException and throw this new

AggregateException.

• This is also true in a Parent-AttachedChild relationship. The

AggregateException can contain other AggregateExceptions!

• Use the AggregateException’s “Flatten” method to bring all these

recursive lists to a single list of exceptions.

Anyone an expert in nested “ForEach” or recursion here????

Facts about exceptions in Tasks

Page 32: Discovering dot net tasks

• Code inside a Task can be protected against unhandled exception like

standard .NET code using a Try-Catch block.

• “Ran to Completion” is the state for a Task that completed normally.

Check it’s IsCompleted property.

• “Faulted” is the state for a Task that completed with an

“AggregateException” thrown. Check it’s IsFaulted property.

• “Canceled” is the state for a Task that completed with a

“TaskCanceledException” thrown. Check it’s IsCanceled property.

Facts about exceptions in Tasks

Page 33: Discovering dot net tasks

• Exceptions in Tasks happen on the Task’s thread not on main thread

• Exceptions in Tasks under Framework 4 will crash your process unless

they are “Observed”.

• A Task’s exception is deemed “Observed” when…

– …the Task’s .Exception property is accessed

– …or you call Wait/WaitAll on the Task

– …or the Task’s Result is accessed.

• The CLR will raise the “UnobservedTaskException” event when an

“Unobserved” Task is FINALIZED (TaskScheduler.UnobservedTaskException +=…)

– You may need to force a GC.Collect to see the event being raised

• This will be your last chance to :

– log the exception that went unhandled

– prevent your process from crashing using the argument’s .SetObserved() method

What’s the Observed Task concept?

Page 34: Discovering dot net tasks

• Exceptions in Tasks under Framework 4.5 no longer crash your process

when they aren’t “Observed” ****** Go back to slide 28!.

• NOT considered a breaking change because the event is triggered.

• You can revert to .NET 4 behavior with a simple config file entry:

What’s the Observed Task concept?

Page 35: Discovering dot net tasks

Disclaimer !

Page 36: Discovering dot net tasks

• If you await a Task, everything changes and AggregateException

no longer get’s thrown, only the FIRST exception is thrown.

• The Task’s Exception property STILL CONTAINS the

AggregateException

Pitfall!

Page 37: Discovering dot net tasks

Disclaimer !

Page 38: Discovering dot net tasks

• What state will a Task be in if you catch an exception that

happen inside the Task and not let it bubble up?

– Completed !!!!

Pitfall!

Page 39: Discovering dot net tasks

Disclaimer !

Page 40: Discovering dot net tasks

• If you create an async void method like this

• …and let potential exceptions bubble up past the async void…

– The Task is deemed “unobserved”

– It will crash your process even under Framework 4.5.

Pitfall!

Page 41: Discovering dot net tasks
Page 42: Discovering dot net tasks

How to handle exceptions? – Demo 6

Page 43: Discovering dot net tasks

Cancellation handling in Tasks

Basics

Cancelling a Task you define

Cancelling a Task you didn’t define

Handling the cancellation

Page 44: Discovering dot net tasks

• What does cancelling execution implies?

– You have a logical operation with a “start” and “end” point

– You want to abruptly terminate this operation before the planned “end” point

– You want to skip all code between “now” and the “end” point and resume right after the

“end” point.

– You do not care what state your operation will be in when you cancel it

– You want to know that the operation was cancelled

• With that in mind, what’s the best way to achieve this?

– Exception !

• Cancellation in Tasks are handled via the following concepts:

– OperationCanceledException or TaskCanceledException

– CancellationTokenSource

– CancellationToken

– CancellationToken.ThrowIfCancellationRequested or CancellationTokenSource.Cancel

– Try-Catch

Basics

Page 45: Discovering dot net tasks

• If you define a Task (Run, StartNew, Start) and wish to build it

cancellable, you must declare a CancellationTokenSource

• You cancel the Task by calling .Cancel() then call

ThrowIfCancellationRequested on the CancellationSource’s Token.

Cancelling a Task you define

Page 46: Discovering dot net tasks

• You are responsible for checking the

CancellationToken regularly inside your

Task.

Cancelling a Task you define

Page 47: Discovering dot net tasks

• Most of the methods to define a Task offer an overload that accepts a

CancellationToken

• This means 2 things:

– Token is “associated” with the Task

– Token checked once before Tasks starts

Cancelling a Task you define

Page 48: Discovering dot net tasks

• When you do not define the Task and simply use a method that returns

a Task and accepts a CancellationToken like this:

• …the Token is “Associated” with the Task like previously

• Obviously means you have no access to the body of the Task and the

Task is responsible for checking for cancellation.

Cancelling a Task you didn’t define

Page 49: Discovering dot net tasks

• Try-Catch… but catch which exception type?

• The right way of canceling a Task is to use

ThrowIfCancellationRequested which will throw an

OperationCanceledException.

• Catch this exception when inside the Task…

Handling the cancellation

Page 50: Discovering dot net tasks

Disclaimer !

Page 51: Discovering dot net tasks

OperationCanceledException

AggregateException

TaskCanceledException

Handling the cancellation

Page 52: Discovering dot net tasks

• A method that accepts a CancellationToken will throw an

OperationCanceledException… Take a look at “Task.Wait()”

• Back to our previous example…

• There is a big difference between canceling a Task and canceling the wait on a

Task

• Why not always catch both AggregateException and

OperationCanceledException and comment the reason why?

Token inside vs outside a Task

Page 53: Discovering dot net tasks

• Do not dive into Tasks without proper readings

– Exception Handling

– Cancellation

– Async - Await

– Task Parallel Library

• http://blogs.msdn.com/b/pfxteam/archive/2011/09/28/10217876.aspx

• http://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

• http://msdn.microsoft.com/en-us/library/jj155759.aspx

Take away!

Page 54: Discovering dot net tasks

Thank You For Attending!!!Vincent GrondinGeneral Manager – Solutions Vet a CDMV subsidiary

C# MVP

.NET Montreal User Group LeaderBlog: http://geekswithblogs.net/vincentgrondin