Concurrency - responsiveness in .NET

57
http://www.slideshare.net/martenrange /

description

Concurrecy - responsiveness in .NET using async/await. These are the slides for NNUG meetup 2014-09-22 in Oslo.

Transcript of Concurrency - responsiveness in .NET

Page 1: Concurrency - responsiveness in .NET

http://www.slideshare.net/martenrange/

Page 2: Concurrency - responsiveness in .NET

Mårten RångeEricsson AB

@marten_range

Page 3: Concurrency - responsiveness in .NET

ConcurrencyExamples for .NET

Page 4: Concurrency - responsiveness in .NET
Page 5: Concurrency - responsiveness in .NET

Responsive

Page 6: Concurrency - responsiveness in .NET

PerformanceScalable algorithms

Page 7: Concurrency - responsiveness in .NET

Three pillars of Concurrency

Scalability (CPU) Parallel.For

Responsiveness Task

async/await

Consistency lock

Interlocked.*

Mutex/Event/Semaphore

Monitor

Page 8: Concurrency - responsiveness in .NET

Responsiveness

Page 9: Concurrency - responsiveness in .NET
Page 10: Concurrency - responsiveness in .NET

string ReadSomeText (string fileName){

using (var sr = new StreamReader(fileName)){

var result = sr.ReadToEnd ();return result;

}}

// Blocks the thread until IO completesvar text = ReadSomeText ("SomeText.txt");

Page 11: Concurrency - responsiveness in .NET

Asyncronous programming allowsprograms to be responsive

Page 12: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

Page 13: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

Page 14: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

Page 15: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var first = await sr.ReadLineAsync();var second = await sr.ReadLineAsync();var third = await sr.ReadLineAsync();return first + second + third;

}}

Page 16: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

// Is this code correct?var readTask = ReadSomeTextAsync ("SomeText.txt");var text = readTask.Result;

Page 17: Concurrency - responsiveness in .NET

It depends

Page 18: Concurrency - responsiveness in .NET

// Is this code correct (ignore exceptions)?async Task<string> ReadSomeTextAsync(string fileName){

++m_readingFiles;using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();--m_readingFiles;return result;

}}

Page 19: Concurrency - responsiveness in .NET

It depends

Page 20: Concurrency - responsiveness in .NET

// Does both TraceTheadId() trace the same id?async Task<string> ReadSomeTextAsync(string fileName){

TraceThreadId ();using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();TraceThreadId ();return result;

}}

Page 21: Concurrency - responsiveness in .NET

It depends

Page 22: Concurrency - responsiveness in .NET

What’s going on?

Page 23: Concurrency - responsiveness in .NET

Your new ”best” friends

SynchronizationContext Console apps

Continues on ThreadPool thread

WindowsFormsSynchronizationContext Used by WindowsForms apps

Continues on the ”UI” thread

DispatcherSynchronizationContext Used by WPF and ASP.NET apps

Continues on the ”same” thread

Page 24: Concurrency - responsiveness in .NET

SynchronizationContext

Page 25: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

// Is this code correct?var readTask = ReadSomeTextAsync ("SomeText.txt");var text = readTask.Result;

Page 26: Concurrency - responsiveness in .NET

Yes

Page 27: Concurrency - responsiveness in .NET

// Is this code correct (ignore exceptions)?async Task<string> ReadSomeTextAsync(string fileName){

++m_readingFiles;using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();--m_readingFiles;return result;

}}

Page 28: Concurrency - responsiveness in .NET

No

Page 29: Concurrency - responsiveness in .NET

// Does both TraceTheadId() trace the same id?async Task<string> ReadSomeTextAsync(string fileName){

TraceThreadId ();using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();TraceThreadId ();return result;

}}

Page 30: Concurrency - responsiveness in .NET

No

Page 31: Concurrency - responsiveness in .NET

DispatcherSynchronizationContext&

WindowsFormsSynchronizationContext

Page 32: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();return result;

}}

// Is this code correct?var readTask = ReadSomeTextAsync ("SomeText.txt");var text = readTask.Result;

Page 33: Concurrency - responsiveness in .NET

No

Page 34: Concurrency - responsiveness in .NET

// Is this code correct (ignore exceptions)?async Task<string> ReadSomeTextAsync(string fileName){

++m_readingFiles;using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();--m_readingFiles;return result;

}}

Page 35: Concurrency - responsiveness in .NET

Yes

Page 36: Concurrency - responsiveness in .NET

// Does both TraceTheadId() trace the same id?async Task<string> ReadSomeTextAsync(string fileName){

TraceThreadId ();using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync();TraceThreadId ();return result;

}}

Page 37: Concurrency - responsiveness in .NET

Yes

Page 38: Concurrency - responsiveness in .NET

So…

Page 39: Concurrency - responsiveness in .NET

Is ”invisible”

Is a thread-global state

Impacts the behavior of your code significantly

As an application developer you can make assumptions

As a library developer you can’t make assumptions

SynchronizationContext

Page 40: Concurrency - responsiveness in .NET

ConfigureAwait

Page 41: Concurrency - responsiveness in .NET

async Task<string> ReadSomeTextAsync(string fileName){

using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync().ConfigureAwait (false);

return result;}

}

// Is this code correct?var readTask = ReadSomeTextAsync ("SomeText.txt");var text = readTask.Result;

Page 42: Concurrency - responsiveness in .NET

Yes

Page 43: Concurrency - responsiveness in .NET

// Is this code correct (ignore exceptions)?async Task<string> ReadSomeTextAsync(string fileName){

++m_readingFiles;using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync().ConfigureAwait (false);

--m_readingFiles;return result;

}}

Page 44: Concurrency - responsiveness in .NET

No

Page 45: Concurrency - responsiveness in .NET

// Does both TraceTheadId() trace the same id?async Task<string> ReadSomeTextAsync(string fileName){

TraceThreadId ();using (var sr = new StreamReader(fileName)){

var result = await sr.ReadToEndAsync().ConfigureAwait (false);

TraceThreadId ();return result;

}}

Page 46: Concurrency - responsiveness in .NET

No

Page 47: Concurrency - responsiveness in .NET

async/await tries to be what we want

Page 48: Concurrency - responsiveness in .NET

async/await reminds me of…

Page 49: Concurrency - responsiveness in .NET

What we need

Do one thing Responsiveness

Predictable semantics Continuation is executed by a thread-pool thread

Visibility Thread-switching should be visible in code

Page 50: Concurrency - responsiveness in .NET

F# async

// Focuses on responsivenesslet gameLoop =

async {// Switching to new thread is explicitdo! Async.SwitchToNewThread ()while true do

// let! is like await in C#let! messages = fromVisual.AsyncDequeue 1000

for message in messages doprocessMessage message

}

Page 51: Concurrency - responsiveness in .NET

C#

yield Special support for enumerators

LINQ Special support for SQL-like syntax

async/await Special support for asynchronous programming

Page 52: Concurrency - responsiveness in .NET

F#

seq { for x in 0..10 -> i } Enumerators implemented using Computation Expressions

query { for c in db.Customers do select c } SQL-like syntax implemented using Computation Expressions

async { let! r=fromVisual.AsyncDequeue 1000 in r } Asynchronous programming using Computation Expressions

Page 53: Concurrency - responsiveness in .NET

Computation Expressions

Page 54: Concurrency - responsiveness in .NET

With async/await always consider the…

Page 55: Concurrency - responsiveness in .NET

SynchronizationContext

SynchronizationContext

SynchronizationContextSynchronizationContext

SynchronizationContextSynchronizationContextSynchronizationContextSynchronizationContext

SynchronizationContextSynchronizationContext

SynchronizationContext

Page 56: Concurrency - responsiveness in .NET

Mårten RångeEricsson AB

@marten_range

Page 57: Concurrency - responsiveness in .NET

Links

Presentation http://www.slideshare.net/martenrange/

Code https://github.com/mrange/presentations/

DIY asynchronous workflows in F# http://mrange.wordpress.com/2014/06/12/diy-asynchronous-workflows-in-f/

Asynchronous programming with async/await http://msdn.microsoft.com/en-us/library/hh191443.aspx