View
197
Download
1
Category
Preview:
DESCRIPTION
Concurrecy - responsiveness in .NET using async/await. These are the slides for NNUG meetup 2014-09-22 in Oslo.
Citation preview
Mårten RångeEricsson AB
@marten_range
ConcurrencyExamples for .NET
Responsive
PerformanceScalable algorithms
Three pillars of Concurrency
Scalability (CPU) Parallel.For
Responsiveness Task
async/await
Consistency lock
Interlocked.*
Mutex/Event/Semaphore
Monitor
Responsiveness
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");
Asyncronous programming allowsprograms to be responsive
async Task<string> ReadSomeTextAsync(string fileName){
using (var sr = new StreamReader(fileName)){
var result = await sr.ReadToEndAsync();return result;
}}
async Task<string> ReadSomeTextAsync(string fileName){
using (var sr = new StreamReader(fileName)){
var result = await sr.ReadToEndAsync();return result;
}}
async Task<string> ReadSomeTextAsync(string fileName){
using (var sr = new StreamReader(fileName)){
var result = await sr.ReadToEndAsync();return result;
}}
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;
}}
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;
It depends
// 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;
}}
It depends
// 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;
}}
It depends
What’s going on?
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
SynchronizationContext
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;
Yes
// 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;
}}
No
// 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;
}}
No
DispatcherSynchronizationContext&
WindowsFormsSynchronizationContext
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;
No
// 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;
}}
Yes
// 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;
}}
Yes
So…
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
ConfigureAwait
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;
Yes
// 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;
}}
No
// 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;
}}
No
async/await tries to be what we want
async/await reminds me of…
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
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
}
C#
yield Special support for enumerators
LINQ Special support for SQL-like syntax
async/await Special support for asynchronous programming
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
Computation Expressions
With async/await always consider the…
SynchronizationContext
SynchronizationContext
SynchronizationContextSynchronizationContext
SynchronizationContextSynchronizationContextSynchronizationContextSynchronizationContext
SynchronizationContextSynchronizationContext
SynchronizationContext
Mårten RångeEricsson AB
@marten_range
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
Recommended