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.

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.
C++ await Deon Brewis std::future additions:
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.
Async Programming WITH ASYNC TASK
Performance evaluation of plagiarism detection method based on the intermediate language Vedran Juričić Tereza Jurić Marija Tkalec.
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 TaskCompletionSource to wrap Tasks around events. Use the threadpool for CPU-bound code, but not.
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.
Advanced .NET Programming I 13th Lecture
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);
PROGRAMMING IN VISUAL BASIC.NET VISUAL BASIC BUILDING BLOCKS Bilal Munir Mughal 1 Chapter-5.
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.
CIS 3301 C# Lesson 13 Interfaces. CIS 3302 Objectives Understand the Purpose of Interfaces. Define an Interface. Use an Interface. Implement Interface.
please wait for the next slide clicking won’t make it come any faster.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 3 Marktoberdorf.
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:
Future of VB and C# Lucian Wischik VB Language PM Microsoft.
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
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
Overview CNS 3260 C#.NET Software Development. 2.NET Framework Began in 2000 Developed in three years (2000 to 2003) Operating System Hardware.NET Framework.
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.
© Stefano Grazioli - Ask for permission for using/quoting: Stefano Grazioli.
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.
1 Handling Errors and Exceptions Chapter 6. 2 Objectives You will be able to: 1. Use the try, catch, and finally statements to handle exceptions. 2. Raise.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming I 7 th Lecture Pavel Ježek
THE FUTURE OF C#: GOOD THINGS COME TO THOSE WHO ‘AWAIT’ Joseph Albahari SESSION CODE: DEV411 (c) 2011 Microsoft. All rights reserved.
The Future of C# and Visual Basic
5/16/2018 © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks.
Frank McCown TechLunch Old Dominion University March 28, 2007
Advanced .NET Programming I 8th Lecture
Program Verification via an Intermediate Verification Language
Advanced .NET Programming I 7th Lecture
CS360 Windows Programming
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.
Async #2 Lucian Wischik Senior Program Manager Microsoft NDC 2012.
Frank McCown TechLunch Old Dominion University March 28, 2007
Advanced .NET Programming I 9th Lecture
Advanced .NET Programming I 8th Lecture
03 | Async Programming & Networking Intro
.NET Core Summer event 2019 – Brno, CZ
Presentation transcript:

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 to catch exceptions thrown from an async void (instead they get posted to the UI message loop) Guidance Use async void methods only for top-level event handlers (and their like) Use async Task-returning methods everywhere else If you need fire-and-forget elsewhere, indicate it explicitly.e.g. “FredAsync().FireAndForget()” When you see an async lambda, verify it

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) {...}... }

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 to catch exceptions thrown from an async void (instead they get posted to the UI message loop) Guidance Use async void methods only for top-level event handlers (and their like) Use async Task-returning methods everywhere else If you need fire-and-forget elsewhere, indicate it explicitly.e.g. “FredAsync().FireAndForget()” When you see an async lambda, verify it

// 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); }

// 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; }

Foo(); var task = FooAsync();... await task;

public static void PausePrint2() { Task t = PausePrintAsync(); t.Wait(); } // “I’m not allowed an async signature, // but my underlying library is async” public static Task PausePrint2Async() { return Task.Run(() => PausePrint()); } // “I want to offer an async signature, // but my underlying library is synchronous” 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"); } “Should I expose async wrappers for synchronous methods?” – generally no!

async Task LoadAsync() { await IO.Network.DownloadAsync(path); } void Button1_Click(){ var t = LoadAsync(); t.Wait(); UpdateView(); } Click Message pump Task... DownloadAsync Task... LoadAsync Download

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 }

Not so for asynchronous methods 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();

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]; }