Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Concurrency - responsiveness in .NET

468 views

Published on

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

Published in: Software
  • Be the first to comment

  • Be the first to like this

Concurrency - responsiveness in .NET

  1. 1. http://www.slideshare.net/martenrange/
  2. 2. Mårten Rånge Ericsson AB @marten_range
  3. 3. Concurrency Examples for .NET
  4. 4. Responsive
  5. 5. Performance Scalable algorithms
  6. 6. Three pillars of Concurrency  Scalability (CPU)  Parallel.For  Responsiveness  Task  async/await  Consistency  lock  Interlocked.*  Mutex/Event/Semaphore  Monitor
  7. 7. Responsiveness
  8. 8. string ReadSomeText (string fileName) { using (var sr = new StreamReader(fileName)) { var result = sr.ReadToEnd (); return result; } } // Blocks the thread until IO completes var text = ReadSomeText ("SomeText.txt");
  9. 9. Asyncronous programming allows programs to be responsive
  10. 10. async Task<string> ReadSomeTextAsync(string fileName) { using (var sr = new StreamReader(fileName)) { var result = await sr.ReadToEndAsync(); return result; } }
  11. 11. async Task<string> ReadSomeTextAsync(string fileName) { using (var sr = new StreamReader(fileName)) { var result = await sr.ReadToEndAsync(); return result; } }
  12. 12. async Task<string> ReadSomeTextAsync(string fileName) { using (var sr = new StreamReader(fileName)) { var result = await sr.ReadToEndAsync(); return result; } }
  13. 13. 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; } }
  14. 14. 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;
  15. 15. It depends
  16. 16. // 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; } }
  17. 17. It depends
  18. 18. // 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; } }
  19. 19. It depends
  20. 20. What’s going on?
  21. 21. 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
  22. 22. SynchronizationContext
  23. 23. 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;
  24. 24. Yes
  25. 25. // 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; } }
  26. 26. No
  27. 27. // 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; } }
  28. 28. No
  29. 29. DispatcherSynchronizationContext & WindowsFormsSynchronizationContext
  30. 30. 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;
  31. 31. No
  32. 32. // 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; } }
  33. 33. Yes
  34. 34. // 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; } }
  35. 35. Yes
  36. 36. So…
  37. 37. SynchronizationContext  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
  38. 38. ConfigureAwait
  39. 39. 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;
  40. 40. Yes
  41. 41. // 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; } }
  42. 42. No
  43. 43. // 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; } }
  44. 44. No
  45. 45. async/await tries to be what we want
  46. 46. async/await reminds me of…
  47. 47. 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
  48. 48. F# async // Focuses on responsiveness let gameLoop = async { // Switching to new thread is explicit do! Async.SwitchToNewThread () while true do // let! is like await in C# let! messages = fromVisual.AsyncDequeue 1000 for message in messages do processMessage message }
  49. 49. C#  yield  Special support for enumerators  LINQ  Special support for SQL-like syntax  async/await  Special support for asynchronous programming
  50. 50. 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
  51. 51. Computation Expressions
  52. 52. With async/await always consider the…
  53. 53. SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext SynchronizationContext
  54. 54. Mårten Rånge Ericsson AB @marten_range
  55. 55. 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

×