Async void is only for top-level event handlers. Use TaskCompletionSource to wrap Tasks around events. Use the threadpool for CPU-bound code, but not.

Slides:



Advertisements
Similar presentations
Mike Barnett RSDE Microsoft Research Nikolai Tillmann RSDE Microsoft Research TL51.
Advertisements

TechReady 16 4/1/2017 Async Clinic
Chapter 1 IDE and Tools for Developing CLR-based Programs Yingcai Xiao.
Ade Azurat, Advanced Programming 2004 (Based on LYS Stefanus’s slides) Advanced Programming 2004, Based on LYS Stefanus’s slides Slide 2.1 Multithreading.
Click async Task LoadSettingsAsync() { await IO.Network.DownloadAsync(path); } async void Button1_Click(){ await LoadSettingsAsync(); UpdateView();
Cole Durdan.  What is asynchronous programming?  Previous patterns  Task Based Async Programming .NET 4.5 Keywords  What happens in an async. method?
Joe Hummel, PhD Microsoft MVP Visual C++ Technical Staff: Pluralsight, LLC Adjunct Professor: U. of Illinois, Chicago and Loyola University Chicago
Asynchronous programming Deadlock All The Things!.
please wait for the next slide clicking won’t make it come any faster.
Principles Async void is a “fire-and-forget” mechanism… The caller is unable to know when an async void has finished The caller is unable.
Async Programming WITH ASYNC TASK
Performance evaluation of plagiarism detection method based on the intermediate language Vedran Juričić Tereza Jurić Marija Tkalec.
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
5.6.2 Thread Synchronization with Semaphores Semaphores can be used to notify other threads that events have occurred –Producer-consumer relationship Producer.
Antonio Cisternino & Diego Colombo VisualStorms Tools Another Brick in the Robot... Università degli Studi di Pisa.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 5 LASER.
Async void is only for top-level event handlers. Use the threadpool for CPU-bound code, but not IO-bound. Use TaskCompletionSource to wrap Tasks around.
Managed Code Generics Language Integrated Query Dynamic + Language Parity C# VB 11.0 Windows Runtime + Asynchrony C# VB 7.0 C# VB.
Introduction to.NET Frank McCown COMP GUI Programming Harding University.
Joe Hummel, PhD Technical Staff: Pluralsight Adjunct Professor: UIC, LUC
Financial Information Management Stefano Grazioli.
DEV301. // Synchronous TResult Foo(...); // Asynchronous Programming Model (APM) IAsyncResult BeginFoo(..., AsyncCallback callback, object state);
Introduction to.NET Frank McCown TechLunch Old Dominion University March 28, 2007.
Click async Task LoadSettingsAsync() { await IO.Network.DownloadAsync(path); } async void Button1_Click(){ await LoadSettingsAsync(); UpdateView();
A Revolutionary Programming Pattern that Will Clean up your Code : Coroutines in C++ David Sackstein ACCU 2015.
please wait for the next slide clicking won’t make it come any faster.
Consuming REST Services from C# SoftUni Team Technical Trainers Software University
Parallel Programming: Responsiveness vs. Performance Joe Hummel, PhD Microsoft MVP Visual C++ Technical Staff: Pluralsight, LLC Professor: U. of Illinois,
public static void PausePrintAsync() { ThreadPool.QueueUserWorkItem(_ => PausePrint()); } public static Task PausePrintAsync() { return Task.Run(()
Joe Hummel, PhD Microsoft MVP Visual C++ Technical Staff: Pluralsight, LLC Professor: U. of Illinois, Chicago stuff:
1 (Worker Queues) cs What is a Thread Pool? A collection of threads that are created once (e.g. when a server starts) That is, no need to create.
Future of VB and C# Lucian Wischik VB Language PM Microsoft.
WHO WILL BENEFIT FROM THIS TALK TOPICS WHAT YOU’LL LEAVE WITH ASP.NET developers, including Web Forms & MVC History of async programming in.NET How async.
Click async Task LoadSettingsAsync() { await IO.Network.DownloadAsync(path); } async void Button1_Click(){ await LoadSettingsAsync(); UpdateView();
ICS 313: Programming Language Theory Chapter 13: Concurrency.

IAsyncResult ar = BeginSomething(…); // Do other work, checking ar.IsCompleted int result = EndSomething(ar);
MSIL C#.NET Software Development. MSIL AKA CIL What all.NET languages compile to What all.NET languages compile to Binary Intermediate Language Binary.
Asynchronous Programming Writing Asynchronous Code in C# SoftUni Team Technical Trainers Software University
Module 8 Enhancing User Interface Responsiveness.
TAP into async programming
please wait for the next slide clicking won’t make it come any faster.
TOPICS WHAT YOU’LL LEAVE WITH WHO WILL BENEFIT FROM THIS TALK.NET library developers : with knowledge of async/await in C# / VB interested in low-level.
Wel come To Seminar On C#.
The Execution System1. 2 Introduction Managed code and managed data qualify code or data that executes in cooperation with the execution engine The execution.
Patterns of Parallel Programming with.NET 4 Stephen Toub Principal Architect Parallel Computing Platform Microsoft Corporation
L6: Threads “the future is parallel” COMP206, Geoff Holmes and Bernhard Pfahringer.
TOPICS WHAT YOU’LL LEAVE WITH WHO WILL BENEFIT FROM THIS TALK.NET developers: familiar with parallel programming support in Visual Studio 2010 and.NET.
C# Present and Future Marita Paletsou Software Engineer.
C# 5.0 Alex Davies 22 nd December What we will cover C# 5.0,.NET 4.5, Visual Studio 11 Caller Info Attributes Upgrade from synchronous to asynchronous.
Asynchronous Programming Writing Concurrent Code in C# SoftUni Team Technical Trainers Software University
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming I 7 th Lecture Pavel Ježek
5/16/2018 © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks.
Advanced Topics in Concurrency and Reactive Programming: Asynchronous Programming Majeed Kassis.
Frank McCown TechLunch Old Dominion University March 28, 2007
Singleton Pattern Command Pattern
Chapter 1 IDE and Tools for Developing CLR-based Programs
Cert Exam Prep: Exam : Programming with C#
12 Asynchronous Programming
TechEd /9/ :20 AM © 2013 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered.
Build /2/2019 © 2012 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks.
Android Topics Asynchronous Callsbacks
Async #2 Lucian Wischik Senior Program Manager Microsoft NDC 2012.
Threads in Java James Brucker.
Using threads for long running tasks.
9. Threads SE2811 Software Component Design
Frank McCown TechLunch Old Dominion University March 28, 2007
03 | Async Programming & Networking Intro
.NET Core Summer event 2019 – Brno, CZ
9. Threads SE2811 Software Component Design
Presentation transcript:

Async void is only for top-level event handlers. Use TaskCompletionSource to wrap Tasks around events. Use the threadpool for CPU-bound code, but not IO-bound, Libraries shouldn't lie, should use ConfigureAwait, should be chunky.

Click async Task LoadSettingsAsync() { await IO.Network.DownloadAsync(path); } async void Button1_Click(){ await LoadSettingsAsync(); UpdateView(); } Click Message pump Task... DownloadAsync Task... LoadSettingsAsync Download LoadSettings

TaskAsync await

' In VB, the expression itself determines void- or Task-returning (not the context). Dim void_returning = Async Sub() Await LoadAsync() : m_Result = "done" End Sub Dim task_returning = Async Function() Await LoadAsync() : m_Result = "done" End Function ' If both overloads are offered, you must give it Task-returning. Await Task.Run(Async Function()... End Function) // In C#, the context determines whether async lambda is void- or Task-returning. Action a1 = async () => { await LoadAsync(); m_Result="done"; }; Func a2 = async () => { await LoadAsync(); m_Result="done"; }; // Q. Which one will it pick? await Task.Run( async () => { await LoadAsync(); m_Result="done"; }); // A. If both overloads are offered, it will pick Task-returning. Good! class Task { static public Task Run(Action a) {...} static public Task Run(Func a) {...}... }

// Usage: await storyboard1.PlayAsync(); public static async Task PlayAsync(this Storyboard storyboard) { var tcs = new TaskCompletionSource (); EventHandler lambda = (s,e) => tcs.TrySetResult(null); try { storyboard.Completed += lambda; storyboard.Begin(); await tcs.Task; } finally { storyboard.Completed -= lambda; } ' Usage: Await storyboard1.PlayAsync() Async Function PlayAsync(sb As Animation.Storyboard) As Task Dim tcs As New TaskCompletionSource(Of Object) Dim lambda As EventHandler(Of Object) = Sub() tcs.TrySetResult(Nothing) Try AddHandler sb.Completed, lambda sb.Begin() Await tcs.Task Finally RemoveHandler sb.Completed, lambda End Try End Function

// Usage: await button1.WhenClicked(); public static async Task WhenClicked(this Button button) { var tcs = new TaskCompletionSource (); RoutedEventHandler lambda = (s,e) => tcs.TrySetResult(null); try { button.Click += lambda; await tcs.Task; } finally { button.Click -= lambda; }

// table1.DataSource = LoadHousesSequentially(1,5); // table1.DataBind(); public List LoadHousesSequentially(int first, int last) { var loadedHouses = new List (); for (int i = first; i <= last; i++) { House house = House.Deserialize(i); loadedHouses.Add(house); } return loadedHouses; } work1 request in response out 500ms work2 work3 work4 work5

response out 300ms work1 work2 work3 work4 work5 Parallel.For request in

end1 start1 end2 start2 end3 start3 end4 start4 end5 start5 response out 500ms request in

1 end1 start1 2 end2 start2 3 end3 start3 5 end5 start5 end1 start1 end2 start2 end5 start5 response out ~200ms Parallel.For request in end3 start3 end4 start4

end2 start1 request in start2 start3 start4 start5 response out ~100ms end5 end1 end3 end4

public async Task > LoadHousesAsync(int first, int last) { var loadedHouses = new List (); var queue = new Queue (Enumerable.Range(first, last – first + 1)); // Throttle the rate of issuing requests... var worker1 = WorkerAsync(queue, loadedHouses); var worker2 = WorkerAsync(queue, loadedHouses); var worker3 = WorkerAsync(queue, loadedHouses); await Task.WhenAll(worker1, worker2, worker3); return loadedHouses; } private async Task WorkerAsync(Queue queue, List results) { while (queue.Count > 0) { int i = queue.Dequeue(); var house = await House.LoadFromDatabaseAsync(i); results.Add(house); } private async Task WorkerAsync(Queue queue, List results) { while (queue.Count > 0) { int i = queue.Dequeue(); var house = await House.LoadFromDatabaseAsync(i); results.Add(house); }

async Task LotsOfWorkAsync() { var throttle = Throttle (async message => { await Task.Yield(); Console.WriteLine(message);}, maxParallelism: Environment.ProcessorCount); throttle.Post("lots"); throttle.Post("of"); throttle.Post("work"); throttle.Complete(); // Signal that we're done enqueuing work. await throttle.Completion; } static ITargetBlock Throttle (Func worker, int max) { var opts = new ExecutionDataflowBlockOptions() {MaxDegreeOfParallelism = max}; return new ActionBlock (worker, opts); }

From the method signature (how people call it) From the method implementation (what resources it uses)

public static void PausePrintAsync() { ThreadPool.QueueUserWorkItem(_ => PausePrint()); } public static Task PausePrintAsync() { return Task.Run(() => PausePrint()); } public static Task PausePrintAsync() { var tcs = new TaskCompletionSource (); new Timer(_ => { Console.WriteLine("Hello"); tcs.SetResult(true); }).Change(10000, Timeout.Infinite); return tcs.Task; } public static async Task PausePrintAsync() { await Task.Delay(10000); Console.WriteLine("Hello"); } Synchronous Asynchronous public static void PausePrint() { var end = DateTime.Now + TimeSpan.FromSeconds(10); while(DateTime.Now < end) { } Console.WriteLine("Hello"); } public static void PausePrint() { Task t = PausePrintAsync(); t.Wait(); }

Use ConfigureAwait(false) async void button1_Click(…) { await DoWorkAsync(); } async void button1_Click(…) { await DoWorkAsync(); } async void button1_Click(…) { DoWorkAsync().Wait(); } async void button1_Click(…) { DoWorkAsync().Wait(); } async Task DoWorkAsync() { await Task.Run(...); Console.WriteLine("Done task"); } async Task DoWorkAsync() { await Task.Run(...); Console.WriteLine("Done task"); } 1. DoWorkAsync invoked on UI thread async Task DoWorkAsync() { await Task.Run(...).ConfigureAwait(false); Console.WriteLine("Done task"); } async Task DoWorkAsync() { await Task.Run(...).ConfigureAwait(false); Console.WriteLine("Done task"); } 2. Task.Run schedules work to run on thread pool User’s app Your library 3. Await captures SynchronizationContext and hooks up a continuation to run when task completes 4. UI blocks waiting for DoWorkAsync-returned Task to complete.ConfigureAwait(false) avoids deadlock.

public static void SimpleBody() { Console.WriteLine("Hello, Async World!"); } public static void SimpleBody() { Console.WriteLine("Hello, Async World!"); }.method public hidebysig static void SimpleBody() cil managed {.maxstack 8 L_0000: ldstr "Hello, Async World!" L_0005: call void [mscorlib]System.Console::WriteLine(string) L_000a: ret }.method public hidebysig static void SimpleBody() cil managed {.maxstack 8 L_0000: ldstr "Hello, Async World!" L_0005: call void [mscorlib]System.Console::WriteLine(string) L_000a: ret }

public static async Task SimpleBody() { Console.WriteLine("Hello, Async World!"); } public static async Task SimpleBody() { Console.WriteLine("Hello, Async World!"); }.method public hidebysig static class [mscorlib]System.Threading.Tasks.Task SimpleBody() cil managed {.custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( ) // Code size 32 (0x20).maxstack 2.locals init ([0] valuetype Program/' d__0' V_0) IL_0000: ldloca.s V_0 IL_0002: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create() IL_0007: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_000c: ldloca.s V_0 IL_000e: call instance void Program/' d__0'::MoveNext() IL_0013: ldloca.s V_0 IL_0015: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_001a: call instance class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task() IL_001f: ret }.method public hidebysig static class [mscorlib]System.Threading.Tasks.Task SimpleBody() cil managed {.custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( ) // Code size 32 (0x20).maxstack 2.locals init ([0] valuetype Program/' d__0' V_0) IL_0000: ldloca.s V_0 IL_0002: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create() IL_0007: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_000c: ldloca.s V_0 IL_000e: call instance void Program/' d__0'::MoveNext() IL_0013: ldloca.s V_0 IL_0015: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_001a: call instance class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task() IL_001f: ret }.method public hidebysig instance void MoveNext() cil managed { // Code size 66 (0x42).maxstack 2.locals init ([0] bool '<>t__doFinallyBodies', [1] class [mscorlib]System.Exception '<>t__ex').try { IL_0000: ldc.i4.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld int32 Program/' d__0'::'<>1__state' IL_0008: ldc.i4.m1 IL_0009: bne.un.s IL_000d IL_000b: leave.s IL_0041 IL_000d: ldstr "Hello, Async World!" IL_0012: call void [mscorlib]System.Console::WriteLine(string) IL_0017: leave.s IL_002f } catch [mscorlib]System.Exception { IL_0019: stloc.1 IL_001a: ldarg.0 IL_001b: ldc.i4.m1 IL_001c: stfld int32 Program/' d__0'::'<>1__state' IL_0021: ldarg.0 IL_0022: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_0027: ldloc.1 IL_0028: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetException( class [mscorlib]System.Exception) IL_002d: leave.s IL_0041 } IL_002f: ldarg.0 IL_0030: ldc.i4.m1 IL_0031: stfld int32 Program/' d__0'::'<>1__state' IL_0036: ldarg.0 IL_0037: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_003c: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetResult() IL_0041: ret }.method public hidebysig instance void MoveNext() cil managed { // Code size 66 (0x42).maxstack 2.locals init ([0] bool '<>t__doFinallyBodies', [1] class [mscorlib]System.Exception '<>t__ex').try { IL_0000: ldc.i4.1 IL_0001: stloc.0 IL_0002: ldarg.0 IL_0003: ldfld int32 Program/' d__0'::'<>1__state' IL_0008: ldc.i4.m1 IL_0009: bne.un.s IL_000d IL_000b: leave.s IL_0041 IL_000d: ldstr "Hello, Async World!" IL_0012: call void [mscorlib]System.Console::WriteLine(string) IL_0017: leave.s IL_002f } catch [mscorlib]System.Exception { IL_0019: stloc.1 IL_001a: ldarg.0 IL_001b: ldc.i4.m1 IL_001c: stfld int32 Program/' d__0'::'<>1__state' IL_0021: ldarg.0 IL_0022: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_0027: ldloc.1 IL_0028: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetException( class [mscorlib]System.Exception) IL_002d: leave.s IL_0041 } IL_002f: ldarg.0 IL_0030: ldc.i4.m1 IL_0031: stfld int32 Program/' d__0'::'<>1__state' IL_0036: ldarg.0 IL_0037: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program/' d__0'::'<>t__builder' IL_003c: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetResult() IL_0041: ret }

public static async Task GetNextIntAsync() { if (m_Count == m_Buf.Length) { m_Buf = await FetchNextBufferAsync(); m_Count = 0; } m_Count += 1; return m_Buf[m_Count - 1]; } public static async Task GetNextIntAsync() { if (m_Count == m_Buf.Length) { m_Buf = await FetchNextBufferAsync(); m_Count = 0; } m_Count += 1; return m_Buf[m_Count - 1]; }

var x = await GetNextIntAsync(); var $awaiter = GetNextIntAsync().GetAwaiter(); if (!$awaiter.IsCompleted) { DO THE AWAIT/RETURN AND RESUME; } var x = $awaiter.GetResult(); var $awaiter = GetNextIntAsync().GetAwaiter(); if (!$awaiter.IsCompleted) { DO THE AWAIT/RETURN AND RESUME; } var x = $awaiter.GetResult();

Async void is only for top-level event handlers. Use TaskCompletionSource to wrap Tasks around events. Use the threadpool for CPU-bound code, but not IO-bound, Libraries shouldn't lie, should use ConfigureAwait, should be chunky.