SlideShare ist ein Scribd-Unternehmen logo
1 von 73
Async and Await on the Server
Doug Jones
So…what’s this about?
 Task-based Asynchronous Pattern on the server
 What is it?
 Why use it?
 How does it work?
 Or…everything I wish I knew about async/await when I started using it!
Life is Asynchronous!
Cooking a Spaghetti Dinner
 Fill pot with water
 Put pot on stove
 Start boiling water (async)
 Do dishes
 When water is boiling… (await)
 Put spaghetti in boiling water (async)
 Start warming up pasta sauce (async)
 Make salad
 Pour drinks
 When spaghetti and sauce finished… (await)
 Make plates of spaghetti with sauce and side salad
Synchronous Cooking!
 Fill pot with water
 Put pot on stove
 Wait for water to boil (just stare at it)
 Put spaghetti in pot
 Wait for spaghetti to cook (stare harder)
 Strain spaghetti
 Fill another pan with pasta sauce
 Put pasta sauce on stove
 Wait for pasta sauce to warm up (keep staring…maybe it helps?)
 Make salad
 Pour drinks
 Make plates of spaghetti with sauce and side salad
Cooking Dinner – The Code
public async Task<Dinner> MakeDinnerAsync()
{
Task boilWaterTask = BoilWaterAsync();
DoDishes();
await boilWaterTask;
Task<Spaghetti> boilSpaghettiTask = BoilSpaghettiAsync();
Task<PastaSauce> warmPastaSauceTask = WarmPastaSauceAsync();
Salad salad = MakeSalad();
Drink drink = GetDrink();
await Task.WhenAll(boilSpaghettiTask, warmPastaSauceTask);
Spaghetti spaghetti = await boilSpaghettiTask;
PastaSauce pastaSauce = await warmPastaSauceTask;
Dinner dinner = MakeDinnerPlate(spaghetti, pastaSauce, salad, drink);
return dinner;
}
This is not about…
 Other forms of concurrency in the Task Parallel Library (TPL)
 Data Parallelism (Parallel.For and ForEach)
 Task Parallelism (Tasks without async/await)
 Parallel LINQ (PLINQ)
 TPL Dataflow
Process – High Level
 An instance of a program running on a computer
 In IIS, a w3wp.exe worker process runs for every
app pool you have running
 NOT for every web application
 *Side Note* Running multiple worker processes for
same web application called a Web Garden
Thread – High Level
 By this I mean .NET CLR MANAGED threads
 1 or more threads to a process
 1 Megabyte memory per thread stack reservation size (by default)
 Expensive to allocate and garbage collect
 Multi-Core compatible
 Using multiple likely means using multiple cores
 Threads distributed amongst CPUs by OS
Threadpool – High Level
 A “pool” or collection of .NET managed threads
 Background worker threads managed by the system
 For quick work without the overhead of allocating a new thread
 Only 1 threadpool per process
Async in ASP.NET video - Levi Broderick
IIS requests – High Level
In ASP.NET, AVOID using thread pool threads
Avoid Threadpool usage in ASP.NET
 Request made in ASP.NET uses a threadpool thread
 That includes any mechanisms that use threadpool threads
 Basically all compute bound parallel processing
 PLINQ
 Task.Run
 Task.Factory.StartNew
 Parallel.For
Promises and Futures
 Promise - a writable, single assignment container which sets the value of the
future (via .SetResult in C#)
 C# - TaskCompletionSource
 Java – SettableFuture
 jQuery - $.Deferred()
 AngularJs - $q.defer()
 ES6 – don’t have direct access, but call resolve or reject within passed in function
 Future - read-only placeholder view of a variable
 C# - Task or Task<T>
 Java - Future
 jQuery - $.Deferred().promise
 AngularJs - $q.defer().promise
 ES6 - new Promise( function (resolve, reject) { ... })
What is async/await?
 Asynchronous programming made easy!
 Almost as easy to do async as it is to do synchronous programming
 Ties in to Task Parallel Library’s Task functionality
 A new language feature in .NET 4.5
 Async/Await released with C# 5.0 (.NET 4.5), released August 2012
 Can compile using VS 2012+
Why async/await?
 For network I/O
 Web service calls
 Database calls
 Cache calls
 Any call to any other server
 Something else doing the work
 Computationally intensive work using Task.Run (avoid in ASP.NET)
 It is doing the work
What methods can be async?
Methods with the following return types can be made async
 Task
 Task<T>
 void //but avoid it!
 async Task
 async Task<T>
 async void
Task – High Level
 Multi-core compatible
 Unit of Work
 POTENTIALLY asynchronous operation
Tasks are like IOUs…
Task t = GetTaskAsync();
 Active task when not…
 t.IsCompleted
 t.IsFaulted
 t.IsCanceled
Synchronous Method
ASYNChronous Method
private async Task<string> GetUrlAsync(string url)
{
using (var client = new HttpClient())
{
return await client.GetStringAsync(url); //network I/O, thread not blocking
}
}
private string GetUrl(string url)
{
using (var client = new WebClient())
{
return client.DownloadString(url);
}
}
What does the async keyword do?
 Lets the method know that it can have await keyword
 Tells the method to wrap the returned value in a Task
 Tells the compiler to generate a LOT of code (another slide)
 It’s an implementation detail
public interface IHttpService
{
Task<string> GetUrlAsync(string url);
}
public class HttpService : IHttpService
{
public async Task<string> GetUrlAsync(string url)
{
string result;
using (var client = new HttpClient())
{
result = await client.GetStringAsync(url); //network I/O
}
return result;
}
}
So…why use it?
private static readonly List<string> Urls = new List<string>
{
"http://blogs.msdn.com/b/pfxteam/",
"http://blog.stephencleary.com/",
"https://channel9.msdn.com/",
"http://www.pluralsight.com/",
"http://stackoverflow.com/"
};
[HttpGet]
[Route("geturlssync")]
public string GetUrls()
{
var watch = Stopwatch.StartNew();
var urlResults = new List<string>();
foreach (string url in Urls)
{
urlResults.Add(GetUrl(url));
}
//LINQ select via method group syntax
//var urlResults = Urls.Select(GetUrl);
return watch.ElapsedMilliseconds.ToString();
}
Test took 3.2 seconds to run
So…why use it? cont’d
[HttpGet]
[Route("geturlsasync")]
public async Task<string> GetUrlsAsync()
{
var watch = Stopwatch.StartNew();
var urlResultsTasks = new List<Task<string>>();
foreach (string url in Urls)
{
urlResultsTasks.Add(GetUrlAsync(url));
}
//LINQ select via method group syntax
//var urlResultsTasks = Urls.Select(GetUrlAsync);
await Task.WhenAll(urlResultsTasks);
return watch.ElapsedMilliseconds.ToString();
}
Test took 1.5 seconds to run AND fewer server resources
Control Flow
https://msdn.microsoft.com/en-us/library/hh191443.aspx
All About Tasks…
using System.Threading.Tasks;
Task.Delay
 Replacement for Thread.Sleep
 Returns completed task after a specified delay
await Task.Delay(1000);
Don’t use Thread.Sleep with async tasks!
WhenAny – more advanced
[HttpGet]
[Route("getfromcacheordb")]
public async Task<string> GetFromCacheOrDb()
{
string retVal = null;
var getFromCacheTask = GetFromCacheAsync();
await Task.WhenAny(getFromCacheTask, Task.Delay(2000));
if (getFromCacheTask.IsCompleted)
{
retVal = await getFromCacheTask;
//perfectly safe to use getFromCacheTask.Result here
//but I won't…see the DANGER ZONE section
}
else
{
var getFromDbTask = GetFromDbAsync();
var taskWithData = await Task.WhenAny(getFromCacheTask, getFromDbTask);
retVal = await taskWithData;
}
return retVal;
}
Generated Async code
public Task<string> GetUrlAsync(string url)
{
HttpService.u003CGetUrlAsyncu003Ed__0 stateMachine;
stateMachine.u003Cu003E4__this = this;
stateMachine.url = url;
stateMachine.u003Cu003Et__builder = AsyncTaskMethodBuilder<string>.Create();
stateMachine.u003Cu003E1__state = -1;
stateMachine.u003Cu003Et__builder.Start<HttpService.u003CGetUrlAsyncu003Ed__0>(ref stateMachine);
return stateMachine.u003Cu003Et__builder.Task;
}
public async Task<string> GetUrlAsync(string url)
{
string result;
using (HttpClient httpClient = new HttpClient())
result = await httpClient.GetStringAsync(url);
return result;
}
compiles to…
Generated Async Code cont’d
[CompilerGenerated]
[StructLayout(LayoutKind.Auto)]
private struct u003CGetUrlAsyncu003Ed__0 : IAsyncStateMachine
{
public int u003Cu003E1__state;
public AsyncTaskMethodBuilder<string> u003Cu003Et__builder;
public HttpService u003Cu003E4__this;
public string url;
public string u003Cresultu003E5__1;
public HttpClient u003Cclientu003E5__2;
private TaskAwaiter<string> u003Cu003Eu__u0024awaiter3;
private object u003Cu003Et__stack;
void IAsyncStateMachine.MoveNext()
{
string result1;
try
{
bool flag = true;
switch (this.u003Cu003E1__state)
{
case -3:
break;
case 0:
try
{
TaskAwaiter<string> awaiter;
if (this.u003Cu003E1__state != 0)
{
awaiter = this.u003Cclientu003E5__2.GetStringAsync(this.url).GetAwaiter();
if (!awaiter.IsCompleted)
{
this.u003Cu003E1__state = 0;
this.u003Cu003Eu__u0024awaiter3 = awaiter;
this.u003Cu003Et__builder.AwaitUnsafeOnCompleted<TaskAwaiter<string>, HttpService.u003CGetUrlAsyncu003Ed__0>(ref awaiter, ref this);
flag = false;
return;
}
}
else
{
awaiter = this.u003Cu003Eu__u0024awaiter3;
this.u003Cu003Eu__u0024awaiter3 = new TaskAwaiter<string>();
this.u003Cu003E1__state = -1;
}
string result2 = awaiter.GetResult();
TaskAwaiter<string> taskAwaiter = new TaskAwaiter<string>();
this.u003Cresultu003E5__1 = result2;
}
finally
{
if (flag && this.u003Cclientu003E5__2 != null)
this.u003Cclientu003E5__2.Dispose();
}
result1 = this.u003Cresultu003E5__1;
break;
default:
this.u003Cclientu003E5__2 = new HttpClient();
goto case 0;
}
}
catch (Exception ex)
{
this.u003Cu003E1__state = -2;
this.u003Cu003Et__builder.SetException(ex);
return;
}
this.u003Cu003E1__state = -2;
this.u003Cu003Et__builder.SetResult(result1);
}
[DebuggerHidden]
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0)
{
this.u003Cu003Et__builder.SetStateMachine(param0);
}
}
SynchronizationContext
.NET applications have a synchronization context
It’s different for each type of app, but fall into buckets
 ASP.NET
 MVC
 WebAPI
 WebForms
 UI
 WPF
 WinForms
 Windows Store app
 Neither
 Console app
SynchronizationContext suggestions
If it’s on the UI or in ASP.NET and you don’t need the context…
don’t continue on captured context
public async Task<string> GetUrlAsync(string url)
{
string result = await GetUrlAsync(url, CancellationToken.None).ConfigureAwait(false);
return result;
}
[HttpGet]
[Route("getrequesturl")]
public async Task<string> GetRequestUrl()
{
await DoingSomethingAsync().ConfigureAwait(continueOnCapturedContext: false);
// And now we're on the thread pool thread without a captured context
//so the HttpContext.Current is null
//so...UNHANDLED EXCEPTION without compiler warning!
return HttpContext.Current.Request.RawUrl;
}
SynchronizationContext suggestions cont’d
But there are places where you do need the context…
My rule of thumb:
 Don’t use .ConfigureAwait(false) on endpoints and ASP.NET pipeline
 MVC controller actions
 WebAPI actions
 Filters
 HttpHandlers
 Http Message Handlers like DelegatingHandler
 Use .ConfigureAwait(false) basically everywhere else
SynchronizationContext suggestions cont’d
The DANGER ZONE
The Deadlock with .Result or .Wait()
 Don’t do .Result or .Wait() on unfinished task
 Or at all…
[HttpGet]
[Route("deadlockdemo")]
public string DeadlockDemo()
{
string urlContent = _httpService.GetUrlAsync("http://finance.yahoo.com").Result;
return urlContent;
}
public async Task<string> GetUrlAsync(string url)
{
string result = await GetUrlAsync(url, CancellationToken.None);
return result;
}
AspNetSynchronizationContext will ensure that they execute one at a time
https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
The Deadlock cont’d
The Deadlock cont’d
Remember the SynchronizationContext?
[HttpGet]
[Route("deadlockdemo")]
public async Task<string> DeadlockDemo()
{
string urlContent = _httpService.GetUrlAsync("http://finance.yahoo.com").Result;
return urlContent;
}
public async Task<string> GetUrlAsync(string url)
{
string result = await GetUrlAsync(url, CancellationToken.None).ConfigureAwait(false);
return result;
}
If ALL awaited tasks are set to configureawait false, the block won’t cause a deadlock
Synchronous Method
public string Echo(string message)
{
return message;
}
ALSO Synchronous Method
public async Task<string> EchoAsync(string message)
{
return message;
}
10x SLOWER!
ALSO Synchronous
public Task<string> EchoAsync2(string message)
{
return Task.FromResult(message);
}
10x SLOWER!
2.5x SLOWER!
public async Task<string> EchoAsync3(string message)
{
return await Task.FromResult(message);
}
Asynchronous, but in Parallel
public async Task<string> GetUrlAsync2()
{
string result = await Task.Run(async () =>
await _httpService.GetUrlAsync("http://blogs.msdn.com/b/pfxteam/")
);
return result;
}
Already an async call, no need for parallel
Synchronous as parallel async?
[HttpGet]
[Route("syncasasync")]
public async Task<string> SyncAsParallelAsync()
{
string retVal = await Task.Run(() => GetUrl("http://blog.stephencleary.com/"));
return retVal;
}
But I need to call an async method
synchronously!
 IF you can’t change the interface
 Can’t change from return of string to return of Task<string> that gets awaited
[HttpGet]
[Route("asyncassync")]
public string AsyncAsSync()
{
string cachedItem = Task.Run(() => GetFromCacheAsync(CancellationToken.None)).Result;
return cachedItem;
}
Avoid if at all possible!
Async void
 Avoid async void!
 Only use async void if you MUST conform to prior interface.
 Primarily for events
private async void btnDownload_Click(object sender, RoutedEventArgs e)
{
btnDownload.IsEnabled = false;
try
{
txtResult.Text = await DownloadStringAsync(txtUrl.Text,
new Progress<int>(p => pbDownloadProgress.Value = p));
}
finally { btnDownload.IsEnabled = true; }
}
Async All The Way
Once you start, you can’t stop…
public static async Task<T> MakeHttpRequestAsync<T>(…)
private async Task<TResult> GetHttpAsync<T, TResult>(…)
public async Task<TResponse> GetRulesEngineResponseAsync(…)
private async Task<SavingsRulesResponse> GetSavingsRulesAsync(…)
public async Task<ExperimentTemplate> CallToActionBuilderAsync(…)
private Task GenerateCallsToActionAndRespondAsync(…)
[System.Web.Http.Route("generatecallstoaction")]
[HttpPost]
public async Task<ApiResponseActionResult> GenerateCallsToActionAsync(…)
Back to the regularly scheduled talk…
using System.Threading.Tasks;
Cancellations
[HttpGet]
[Route("geturlsasync")]
public async Task<string> GetUrlsAsync()
{
var watch = Stopwatch.StartNew();
var cts = new CancellationTokenSource(1000);
var urlResultsTasks = new List<Task<string>>();
try
{
urlResultsTasks = Urls.Select(url => _httpService.GetUrlAsync(url, cts.Token)).ToList();
await Task.WhenAll(urlResultsTasks);
}
catch (TaskCanceledException ex)
{
//swallow ex for now
}
return string.Format("Cancelled Tasks: {0} Elapsed Time In MS: {1}",
urlResultsTasks.Count(x => x.IsCanceled), watch.ElapsedMilliseconds);
}
OUTPUT: "Cancelled Tasks: 1 Elapsed Time In MS: 1152"
Cancellations cont’d
The trickle down effect of cancellation code
public async Task<string> GetUrlAsync(string url,CancellationToken cancellationToken)
{
string result;
var uri = new Uri(url);
using (var client = new HttpClient())
{
cancellationToken.ThrowIfCancellationRequested(); //optional
var response = await client.GetAsync(uri, cancellationToken); //network I/O
cancellationToken.ThrowIfCancellationRequested(); //optional
result = await response.Content.ReadAsStringAsync(); //potentially network I/O
}
return result;
}
Cancellations linked
[HttpGet]
[Route("geturlsasync2")]
//[AsyncTimeout(1500)] for MVC only
public async Task<string> GetUrlsAsync2(CancellationToken cancellationToken)
{
var watch = Stopwatch.StartNew();
var cts = new CancellationTokenSource(1000);
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cts.Token);
var urlResultsTasks = new List<Task<string>>();
try
{
urlResultsTasks = Urls.Select(url => _httpService.GetUrlAsync(url, linkedCts.Token)).ToList();
await Task.WhenAll(urlResultsTasks);
}
catch (TaskCanceledException ex)
{
//swallow ex for now
}
return string.Format("Cancelled Tasks: {0} Elapsed Time In MS: {1}",
urlResultsTasks.Count(x => x.IsCanceled), watch.ElapsedMilliseconds);
}
Async lambdas
Can use async on Action<T> and Func<T> types
[HttpGet]
[Route("asynclambda")]
public async Task<string> AsyncLambda()
{
string closureMessage = null;
var task = ExecuteAsyncAndLogTime("GetFromCacheAsync", async () =>
{
closureMessage = await GetFromCacheAsync(CancellationToken.None);
});
await task;
return closureMessage;
}
private async Task ExecuteAsyncAndLogTime(string title, Func<Task> asyncAction)
{
var watch = Stopwatch.StartNew();
await asyncAction.Invoke();
Debug.WriteLine("{0} ElapsedTimeInMs: {1}", title, watch.ElapsedMilliseconds);
}
Async lambdas cont’d
The Try Tri!
public static async Task<T> DoAsync<T>(Func<Task<T>> action, TimeSpan retryInterval,
int retryCount = 3)
{
var exceptions = new List<Exception>();
for (int retry = 0; retry < retryCount; retry++)
{
if (retry > 0)
{
await Task.Delay(retryInterval);
}
try
{
return await action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
Task.FromResult
[HttpGet]
[Route("fromresult")]
public async Task<string> FromResult()
{
string closureMessage = null;
var task = ExecuteAsyncAndLogTime("Synchronous",() =>
{
closureMessage = GetText();
return Task.FromResult(0);
//.NET 4.6 has Task.CompletedTask for this
});
await task;
return closureMessage;
}
Hot and Cold methods
 All async tasks run HOT
 As soon as task created, method is started (like regular method)
[HttpGet]
[Route("getfromcache")]
public async Task<string> GetFromCache()
{
var getFromCacheTask = GetFromCacheAsync(CancellationToken.None);
SomethingSynchronous();
string cachedItem = await getFromCacheTask;
return cachedItem;
}
Note: GetFromCacheAsync takes 0.5 seconds and SomethingSynchronous takes 1 second
Total time was 1.149 seconds
Cold Tasks (.NET 4.0)
[HttpGet]
[Route("coldtask")]
public void ColdTask()
{
var task = new Task(() =>
{
SomethingSynchronous();
// ...and some more stuff
});
task.Start();
}
If you have a need, could be useful for computationally bound asynchrony, but…
You should probably AVOID this
Exceptions
[HttpGet]
[Route("throwerror")]
public async Task<string> ThrowErrorAsync()
{
string message = null;
var t = ThrowErrorCoreAsync();
try
{
message = await t;
}
catch (Exception ex)
{
return "ERROR awaiting";
}
return message;
}
private async Task<string> ThrowErrorCoreAsync()
{
throw new Exception("Error!");
await GetFromDbAsync(CancellationToken.None);
}
Work basically how you’d expect…
Exceptions cont’d
Well…almost
private async Task GetMultipleErrorsAsync()
{
var t1 = ThrowErrorCoreAsync();
var t2 = ThrowErrorCoreAsync2();
var t3 = ThrowErrorCoreAsync3();
var tAll = Task.WhenAll(t1, t2, t3);
try
{
await tAll;
}
catch (Exception ex)
{
Debugger.Break();
}
}
Exception thrown is error from t1, but tAll has AggregateException of all 3 errors
Aync Http
public async Task<string> GetUrlAsync(string url,CancellationToken cancellationToken)
{
string result;
var uri = new Uri(url);
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false); //network I/O
result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); //potentially network I/O
}
return result;
}
Service References
Service References cont’d
public static async Task Foo()
{
using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
{
Task<string> t = client.GetDataAsync(1);
string result = await t;
}
}
ADO.NET
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand(commandString, connection))
{
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
//Some code
if (await reader.ReadAsync())
{
//more code
}
//Other code
}
}
}
Entity Framework 6
public static async Task PerformDatabaseOperations()
{
using (var db = new BloggingContext())
{
// Create a new blog and save it
db.Blogs.Add(new Blog
{
Name = "Test Blog #" + (db.Blogs.Count() + 1)
});
Console.WriteLine("Calling SaveChanges.");
await db.SaveChangesAsync();
Console.WriteLine("SaveChanges completed.");
// Query for all blogs ordered by name
Console.WriteLine("Executing query.");
var blogs = await (from b in db.Blogs
orderby b.Name
select b).ToListAsync();
// Write all blogs out to Console
Console.WriteLine("Query completed with following results:");
foreach (var blog in blogs)
{
Console.WriteLine(" - " + blog.Name);
}
}
}
EF 6 stored procedure async
with Table-Valued Parameter
public async Task UpdateSoftOfferEndpointsActiveFlag(Dictionary<string, bool> softOfferEndpointDictionary)
{
const string sql = "exec [SavingsEngine].[pUpdateSoftOfferEndpointsActiveFlag]
@ipSoftOfferEndpointDictionary";
if (softOfferEndpointDictionary == null || !softOfferEndpointDictionary.Any())
{
return;
}
var ipSoftOfferEndpointDictionaryParameter = new SqlParameter("@ipSoftOfferEndpointDictionary",
System.Data.SqlDbType.Structured) { TypeName = "SavingsEngine.DictionaryStringBit" };
var temp = new System.Data.DataTable();
temp.Columns.Add("Key", typeof(string));
temp.Columns.Add("Value", typeof(bool));
foreach (var kvp in softOfferEndpointDictionary)
{
temp.Rows.Add(kvp.Key, kvp.Value);
}
ipSoftOfferEndpointDictionaryParameter.Value = temp;
await _cbasContext.Database.ExecuteSqlCommandAsync(sql,
ipSoftOfferEndpointDictionaryParameter).ConfigureAwait(false);
}
Redis
StackExchange.Redis
https://github.com/StackExchange/StackExchange.Redis
string value = "abcdefg";
await db.StringSetAsync("mykey", value);
...
string value = await db.StringGetAsync("mykey");
Console.WriteLine(value); // writes: "abcdefg"
public async Task SetRecaptchaCache(ConsumerType model)
{
string recaptchaHashKey = GetRecaptchaHashKey(model);
await m_redis.StringSetAsync(recaptchaHashKey, true,
TimeSpan.FromMinutes(10)).ConfigureAwait(false);
}
MongoDB
https://github.com/mongodb/mongo-csharp-driver
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("foo");
var collection = database.GetCollection<Person>("bar");
await collection.InsertOneAsync(new Person { Name = "Jack" });
var list = await collection.Find(x => x.Name == "Jack") .ToListAsync();
foreach(var person in list)
{
Console.WriteLine(person.Name);
}
Amazon Web Services
http://docs.aws.amazon.com/sdkfornet/latest/apidocs/Index.html
 Simple Notification Service (SNS)
 public virtual Task<PublishResponse> PublishAsync( PublishRequest
request, CancellationToken cancellationToken )
 Simple Queue Service (SQS)
 public virtual Task<SendMessageResponse> SendMessageAsync(
SendMessageRequest request, CancellationToken cancellationToken)
 Simple Storage Service (S3)
 public virtual Task<GetObjectResponse> GetObjectAsync(
GetObjectRequest request, CancellationToken cancellationToken )
New in .NET 4.6
 Not much…
 Task.FromException
 Task.FromCancelled
 Task.CompletedTask
 Task{Creation/Continuation}Options.RunContinuationsAsynchronously
 Allows you to run .SetResult within a lock
 Except…
 Now able to await in catch and finally blocks!
Conclusion
 Code the way you live, asynchronously!
 That is, code NETWORK I/O calls asynchronously
 But…
 Don’t use async on synchronously running code
 Test the performance. Is it saving time?
Questions?
Why run this as async?
[HttpGet]
[Route("geturlasync")]
public async Task<string> GetUrlAsync()
{
string result = await _httpService.GetUrlAsync("http://blogs.msdn.com/b/pfxteam/");
return result;
}
 There is no thread!
 When the thread has no more work to do while awaiting, it goes back to the threadpool
 Increased server throughput
 Server can process more requests
Task.Yield
Copied from TAP doc
https://www.microsoft.com/en-us/download/details.aspx?id=19957
Task.Run(async delegate
{
for(int i=0; i<1000000; i++)
{
await Task.Yield(); // fork the continuation into a separate work item
...
}
});
public static Task<string> DownloadStringAsync(Uri url)
{
var tcs = new TaskCompletionSource<string>();
var wc = new WebClient();
wc.DownloadStringCompleted += (s,e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wc.DownloadStringAsync(url);
return tcs.Task;
}
TaskCompletionSource and EAP
Copied from TAP doc
https://www.microsoft.com/en-us/download/details.aspx?id=19957
Meet the experts
 Stephen Toub
 On Visual Studio Parallel Programming team at
Microsoft
 http://blogs.msdn.com/b/pfxteam/
 Wrote THE document on the TAP
 https://www.microsoft.com/en-
us/download/details.aspx?id=19957
 Speaker at MS Build 2011,2013
Meet the experts cont’d
 Stephen Cleary
 Microsoft MVP
 Avid StackOverflow user
 Answered my async/await
question
 Great blog
 http://blog.stephencleary.com/
 Wrote the book on concurrency
 Concurrency in C# Cookbook on
Amazon
References
 The Task-based Asynchronous Pattern
 The zen of async: Best practices for best performance
 MS Build 2011 video – Stephen Toub
 Async in ASP.NET video with Damian Edwards et al.
 Async'ing Your Way to a Successful App with .NET
 MS Build 2013 video – Stephen Toub
 Building parallelized apps with .NET and Visual Studio
 MS Build 2011 video – Stephen Toub
 Stephen Toub: Task-Based Asynchrony with Async

Weitere ähnliche Inhalte

Was ist angesagt?

Async-await best practices in 10 minutes
Async-await best practices in 10 minutesAsync-await best practices in 10 minutes
Async-await best practices in 10 minutesPaulo Morgado
 
Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Mindfire Solutions
 
Using Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek SafarUsing Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek SafarXamarin
 
Async Await for Mobile Apps
Async Await for Mobile AppsAsync Await for Mobile Apps
Async Await for Mobile AppsCraig Dunn
 
Task parallel library presentation
Task parallel library presentationTask parallel library presentation
Task parallel library presentationahmed sayed
 
Reactive programming with Rxjava
Reactive programming with RxjavaReactive programming with Rxjava
Reactive programming with RxjavaChristophe Marchal
 
Real world functional reactive programming
Real world functional reactive programmingReal world functional reactive programming
Real world functional reactive programmingEric Polerecky
 
Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013slandelle
 
Introduction to Python Celery
Introduction to Python CeleryIntroduction to Python Celery
Introduction to Python CeleryMahendra M
 
Gude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic ServerGude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic ServerApache Traffic Server
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxAndrzej Sitek
 
Reflection in Pharo5
Reflection in Pharo5Reflection in Pharo5
Reflection in Pharo5Marcus Denker
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and pythonChetan Giridhar
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Martin Toshev
 
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node jsThomas Roch
 
How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.jsPiotr Pelczar
 
The Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesHaim Yadid
 

Was ist angesagt? (20)

Async-await best practices in 10 minutes
Async-await best practices in 10 minutesAsync-await best practices in 10 minutes
Async-await best practices in 10 minutes
 
Async/Await
Async/AwaitAsync/Await
Async/Await
 
Async await...oh wait!
Async await...oh wait!Async await...oh wait!
Async await...oh wait!
 
Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1
 
Using Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek SafarUsing Async in your Mobile Apps - Marek Safar
Using Async in your Mobile Apps - Marek Safar
 
Async Await for Mobile Apps
Async Await for Mobile AppsAsync Await for Mobile Apps
Async Await for Mobile Apps
 
Task parallel library presentation
Task parallel library presentationTask parallel library presentation
Task parallel library presentation
 
Reactive programming with Rxjava
Reactive programming with RxjavaReactive programming with Rxjava
Reactive programming with Rxjava
 
Real world functional reactive programming
Real world functional reactive programmingReal world functional reactive programming
Real world functional reactive programming
 
Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013
 
RxJava Applied
RxJava AppliedRxJava Applied
RxJava Applied
 
Introduction to Python Celery
Introduction to Python CeleryIntroduction to Python Celery
Introduction to Python Celery
 
Gude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic ServerGude for C++11 in Apache Traffic Server
Gude for C++11 in Apache Traffic Server
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
 
Reflection in Pharo5
Reflection in Pharo5Reflection in Pharo5
Reflection in Pharo5
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and python
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
 
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node js
 
How NOT to write in Node.js
How NOT to write in Node.jsHow NOT to write in Node.js
How NOT to write in Node.js
 
The Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFutures
 

Andere mochten auch

Mono for .NET Developers
Mono for .NET DevelopersMono for .NET Developers
Mono for .NET Developersjeffz
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Baruch Sadogursky
 
From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!Gil Tayar
 
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...Lviv Startup Club
 
How to meets Async and Task
How to meets Async and TaskHow to meets Async and Task
How to meets Async and TaskKouji Matsui
 
Sync with async
Sync with  asyncSync with  async
Sync with asyncprabathsl
 
Promises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back AgainPromises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back AgainHans-Gunther Schmidt
 
Multithreading, Blocking IO and Async IO
Multithreading, Blocking IO and Async IOMultithreading, Blocking IO and Async IO
Multithreading, Blocking IO and Async IODirecti Group
 
Servlet 3.1 Async I/O
Servlet 3.1 Async I/OServlet 3.1 Async I/O
Servlet 3.1 Async I/OSimone Bordet
 
Sync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-ioSync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-ioCheoloh Bae
 
Syncing Async
Syncing AsyncSyncing Async
Syncing AsyncFITC
 
Asynchronous programming in ASP.NET
Asynchronous programming in ASP.NETAsynchronous programming in ASP.NET
Asynchronous programming in ASP.NETAlex Thissen
 

Andere mochten auch (13)

Mono for .NET Developers
Mono for .NET DevelopersMono for .NET Developers
Mono for .NET Developers
 
Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java Everything you wanted to know about writing async, concurrent http apps in java
Everything you wanted to know about writing async, concurrent http apps in java
 
From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!From Callback Hell to Async Heaven - Promises!
From Callback Hell to Async Heaven - Promises!
 
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
Lviv MD Day 2015 Олексій Демедецький "Using Future for async flow application...
 
How to meets Async and Task
How to meets Async and TaskHow to meets Async and Task
How to meets Async and Task
 
Sync with async
Sync with  asyncSync with  async
Sync with async
 
Promises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back AgainPromises And Chaining In AngularJS - Into Callback Hell And Back Again
Promises And Chaining In AngularJS - Into Callback Hell And Back Again
 
Multithreading, Blocking IO and Async IO
Multithreading, Blocking IO and Async IOMultithreading, Blocking IO and Async IO
Multithreading, Blocking IO and Async IO
 
Servlet 3.1 Async I/O
Servlet 3.1 Async I/OServlet 3.1 Async I/O
Servlet 3.1 Async I/O
 
Sync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-ioSync async-blocking-nonblocking-io
Sync async-blocking-nonblocking-io
 
Think Async in Java 8
Think Async in Java 8Think Async in Java 8
Think Async in Java 8
 
Syncing Async
Syncing AsyncSyncing Async
Syncing Async
 
Asynchronous programming in ASP.NET
Asynchronous programming in ASP.NETAsynchronous programming in ASP.NET
Asynchronous programming in ASP.NET
 

Ähnlich wie Async and Await on the Server

Asynchronous programming - .NET Way
Asynchronous programming - .NET WayAsynchronous programming - .NET Way
Asynchronous programming - .NET WayBishnu Rawal
 
.Net Multithreading and Parallelization
.Net Multithreading and Parallelization.Net Multithreading and Parallelization
.Net Multithreading and ParallelizationDmitri Nesteruk
 
Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#Rainer Stropek
 
Async ASP.NET Applications
Async ASP.NET ApplicationsAsync ASP.NET Applications
Async ASP.NET ApplicationsShayne Boyer
 
Asynchronous Programming in .NET
Asynchronous Programming in .NETAsynchronous Programming in .NET
Asynchronous Programming in .NETPierre-Luc Maheu
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA PresentationRob Tweed
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Yoshifumi Kawai
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyDavid Gómez García
 
Copper: A high performance workflow engine
Copper: A high performance workflow engineCopper: A high performance workflow engine
Copper: A high performance workflow enginedmoebius
 
Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022David Gómez García
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio
 
Play framework productivity formula
Play framework   productivity formula Play framework   productivity formula
Play framework productivity formula Sorin Chiprian
 
Parallel Processing
Parallel ProcessingParallel Processing
Parallel ProcessingRTigger
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9Ilya Grigorik
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSTechWell
 
Ordina SOFTC Presentation - Async CTP
Ordina SOFTC Presentation - Async CTPOrdina SOFTC Presentation - Async CTP
Ordina SOFTC Presentation - Async CTPOrdina Belgium
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOMykola Novik
 

Ähnlich wie Async and Await on the Server (20)

Asynchronous programming - .NET Way
Asynchronous programming - .NET WayAsynchronous programming - .NET Way
Asynchronous programming - .NET Way
 
Training – Going Async
Training – Going AsyncTraining – Going Async
Training – Going Async
 
.Net Multithreading and Parallelization
.Net Multithreading and Parallelization.Net Multithreading and Parallelization
.Net Multithreading and Parallelization
 
Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#Workshop: Async and Parallel in C#
Workshop: Async and Parallel in C#
 
Async ASP.NET Applications
Async ASP.NET ApplicationsAsync ASP.NET Applications
Async ASP.NET Applications
 
Asynchronous Programming in .NET
Asynchronous Programming in .NETAsynchronous Programming in .NET
Asynchronous Programming in .NET
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
rioinfo2012
rioinfo2012rioinfo2012
rioinfo2012
 
Copper: A high performance workflow engine
Copper: A high performance workflow engineCopper: A high performance workflow engine
Copper: A high performance workflow engine
 
Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022Leverage CompletableFutures to handle async queries. DevNexus 2022
Leverage CompletableFutures to handle async queries. DevNexus 2022
 
Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0Binary Studio Academy: Concurrency in C# 5.0
Binary Studio Academy: Concurrency in C# 5.0
 
Webscraping with asyncio
Webscraping with asyncioWebscraping with asyncio
Webscraping with asyncio
 
Play framework productivity formula
Play framework   productivity formula Play framework   productivity formula
Play framework productivity formula
 
Parallel Processing
Parallel ProcessingParallel Processing
Parallel Processing
 
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9No callbacks, No Threads - Cooperative web servers in Ruby 1.9
No callbacks, No Threads - Cooperative web servers in Ruby 1.9
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
Ordina SOFTC Presentation - Async CTP
Ordina SOFTC Presentation - Async CTPOrdina SOFTC Presentation - Async CTP
Ordina SOFTC Presentation - Async CTP
 
BUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIOBUILDING APPS WITH ASYNCIO
BUILDING APPS WITH ASYNCIO
 

Kürzlich hochgeladen

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Kürzlich hochgeladen (20)

SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

Async and Await on the Server

  • 1. Async and Await on the Server Doug Jones
  • 2. So…what’s this about?  Task-based Asynchronous Pattern on the server  What is it?  Why use it?  How does it work?  Or…everything I wish I knew about async/await when I started using it!
  • 3. Life is Asynchronous! Cooking a Spaghetti Dinner  Fill pot with water  Put pot on stove  Start boiling water (async)  Do dishes  When water is boiling… (await)  Put spaghetti in boiling water (async)  Start warming up pasta sauce (async)  Make salad  Pour drinks  When spaghetti and sauce finished… (await)  Make plates of spaghetti with sauce and side salad
  • 4. Synchronous Cooking!  Fill pot with water  Put pot on stove  Wait for water to boil (just stare at it)  Put spaghetti in pot  Wait for spaghetti to cook (stare harder)  Strain spaghetti  Fill another pan with pasta sauce  Put pasta sauce on stove  Wait for pasta sauce to warm up (keep staring…maybe it helps?)  Make salad  Pour drinks  Make plates of spaghetti with sauce and side salad
  • 5. Cooking Dinner – The Code public async Task<Dinner> MakeDinnerAsync() { Task boilWaterTask = BoilWaterAsync(); DoDishes(); await boilWaterTask; Task<Spaghetti> boilSpaghettiTask = BoilSpaghettiAsync(); Task<PastaSauce> warmPastaSauceTask = WarmPastaSauceAsync(); Salad salad = MakeSalad(); Drink drink = GetDrink(); await Task.WhenAll(boilSpaghettiTask, warmPastaSauceTask); Spaghetti spaghetti = await boilSpaghettiTask; PastaSauce pastaSauce = await warmPastaSauceTask; Dinner dinner = MakeDinnerPlate(spaghetti, pastaSauce, salad, drink); return dinner; }
  • 6. This is not about…  Other forms of concurrency in the Task Parallel Library (TPL)  Data Parallelism (Parallel.For and ForEach)  Task Parallelism (Tasks without async/await)  Parallel LINQ (PLINQ)  TPL Dataflow
  • 7. Process – High Level  An instance of a program running on a computer  In IIS, a w3wp.exe worker process runs for every app pool you have running  NOT for every web application  *Side Note* Running multiple worker processes for same web application called a Web Garden
  • 8. Thread – High Level  By this I mean .NET CLR MANAGED threads  1 or more threads to a process  1 Megabyte memory per thread stack reservation size (by default)  Expensive to allocate and garbage collect  Multi-Core compatible  Using multiple likely means using multiple cores  Threads distributed amongst CPUs by OS
  • 9. Threadpool – High Level  A “pool” or collection of .NET managed threads  Background worker threads managed by the system  For quick work without the overhead of allocating a new thread  Only 1 threadpool per process
  • 10. Async in ASP.NET video - Levi Broderick IIS requests – High Level In ASP.NET, AVOID using thread pool threads
  • 11. Avoid Threadpool usage in ASP.NET  Request made in ASP.NET uses a threadpool thread  That includes any mechanisms that use threadpool threads  Basically all compute bound parallel processing  PLINQ  Task.Run  Task.Factory.StartNew  Parallel.For
  • 12. Promises and Futures  Promise - a writable, single assignment container which sets the value of the future (via .SetResult in C#)  C# - TaskCompletionSource  Java – SettableFuture  jQuery - $.Deferred()  AngularJs - $q.defer()  ES6 – don’t have direct access, but call resolve or reject within passed in function  Future - read-only placeholder view of a variable  C# - Task or Task<T>  Java - Future  jQuery - $.Deferred().promise  AngularJs - $q.defer().promise  ES6 - new Promise( function (resolve, reject) { ... })
  • 13. What is async/await?  Asynchronous programming made easy!  Almost as easy to do async as it is to do synchronous programming  Ties in to Task Parallel Library’s Task functionality  A new language feature in .NET 4.5  Async/Await released with C# 5.0 (.NET 4.5), released August 2012  Can compile using VS 2012+
  • 14. Why async/await?  For network I/O  Web service calls  Database calls  Cache calls  Any call to any other server  Something else doing the work  Computationally intensive work using Task.Run (avoid in ASP.NET)  It is doing the work
  • 15. What methods can be async? Methods with the following return types can be made async  Task  Task<T>  void //but avoid it!  async Task  async Task<T>  async void
  • 16. Task – High Level  Multi-core compatible  Unit of Work  POTENTIALLY asynchronous operation
  • 17. Tasks are like IOUs… Task t = GetTaskAsync();  Active task when not…  t.IsCompleted  t.IsFaulted  t.IsCanceled
  • 18. Synchronous Method ASYNChronous Method private async Task<string> GetUrlAsync(string url) { using (var client = new HttpClient()) { return await client.GetStringAsync(url); //network I/O, thread not blocking } } private string GetUrl(string url) { using (var client = new WebClient()) { return client.DownloadString(url); } }
  • 19. What does the async keyword do?  Lets the method know that it can have await keyword  Tells the method to wrap the returned value in a Task  Tells the compiler to generate a LOT of code (another slide)  It’s an implementation detail public interface IHttpService { Task<string> GetUrlAsync(string url); } public class HttpService : IHttpService { public async Task<string> GetUrlAsync(string url) { string result; using (var client = new HttpClient()) { result = await client.GetStringAsync(url); //network I/O } return result; } }
  • 20. So…why use it? private static readonly List<string> Urls = new List<string> { "http://blogs.msdn.com/b/pfxteam/", "http://blog.stephencleary.com/", "https://channel9.msdn.com/", "http://www.pluralsight.com/", "http://stackoverflow.com/" }; [HttpGet] [Route("geturlssync")] public string GetUrls() { var watch = Stopwatch.StartNew(); var urlResults = new List<string>(); foreach (string url in Urls) { urlResults.Add(GetUrl(url)); } //LINQ select via method group syntax //var urlResults = Urls.Select(GetUrl); return watch.ElapsedMilliseconds.ToString(); } Test took 3.2 seconds to run
  • 21. So…why use it? cont’d [HttpGet] [Route("geturlsasync")] public async Task<string> GetUrlsAsync() { var watch = Stopwatch.StartNew(); var urlResultsTasks = new List<Task<string>>(); foreach (string url in Urls) { urlResultsTasks.Add(GetUrlAsync(url)); } //LINQ select via method group syntax //var urlResultsTasks = Urls.Select(GetUrlAsync); await Task.WhenAll(urlResultsTasks); return watch.ElapsedMilliseconds.ToString(); } Test took 1.5 seconds to run AND fewer server resources
  • 23. All About Tasks… using System.Threading.Tasks;
  • 24. Task.Delay  Replacement for Thread.Sleep  Returns completed task after a specified delay await Task.Delay(1000); Don’t use Thread.Sleep with async tasks!
  • 25. WhenAny – more advanced [HttpGet] [Route("getfromcacheordb")] public async Task<string> GetFromCacheOrDb() { string retVal = null; var getFromCacheTask = GetFromCacheAsync(); await Task.WhenAny(getFromCacheTask, Task.Delay(2000)); if (getFromCacheTask.IsCompleted) { retVal = await getFromCacheTask; //perfectly safe to use getFromCacheTask.Result here //but I won't…see the DANGER ZONE section } else { var getFromDbTask = GetFromDbAsync(); var taskWithData = await Task.WhenAny(getFromCacheTask, getFromDbTask); retVal = await taskWithData; } return retVal; }
  • 26. Generated Async code public Task<string> GetUrlAsync(string url) { HttpService.u003CGetUrlAsyncu003Ed__0 stateMachine; stateMachine.u003Cu003E4__this = this; stateMachine.url = url; stateMachine.u003Cu003Et__builder = AsyncTaskMethodBuilder<string>.Create(); stateMachine.u003Cu003E1__state = -1; stateMachine.u003Cu003Et__builder.Start<HttpService.u003CGetUrlAsyncu003Ed__0>(ref stateMachine); return stateMachine.u003Cu003Et__builder.Task; } public async Task<string> GetUrlAsync(string url) { string result; using (HttpClient httpClient = new HttpClient()) result = await httpClient.GetStringAsync(url); return result; } compiles to…
  • 27. Generated Async Code cont’d [CompilerGenerated] [StructLayout(LayoutKind.Auto)] private struct u003CGetUrlAsyncu003Ed__0 : IAsyncStateMachine { public int u003Cu003E1__state; public AsyncTaskMethodBuilder<string> u003Cu003Et__builder; public HttpService u003Cu003E4__this; public string url; public string u003Cresultu003E5__1; public HttpClient u003Cclientu003E5__2; private TaskAwaiter<string> u003Cu003Eu__u0024awaiter3; private object u003Cu003Et__stack; void IAsyncStateMachine.MoveNext() { string result1; try { bool flag = true; switch (this.u003Cu003E1__state) { case -3: break; case 0: try { TaskAwaiter<string> awaiter; if (this.u003Cu003E1__state != 0) { awaiter = this.u003Cclientu003E5__2.GetStringAsync(this.url).GetAwaiter(); if (!awaiter.IsCompleted) { this.u003Cu003E1__state = 0; this.u003Cu003Eu__u0024awaiter3 = awaiter; this.u003Cu003Et__builder.AwaitUnsafeOnCompleted<TaskAwaiter<string>, HttpService.u003CGetUrlAsyncu003Ed__0>(ref awaiter, ref this); flag = false; return; } } else { awaiter = this.u003Cu003Eu__u0024awaiter3; this.u003Cu003Eu__u0024awaiter3 = new TaskAwaiter<string>(); this.u003Cu003E1__state = -1; } string result2 = awaiter.GetResult(); TaskAwaiter<string> taskAwaiter = new TaskAwaiter<string>(); this.u003Cresultu003E5__1 = result2; } finally { if (flag && this.u003Cclientu003E5__2 != null) this.u003Cclientu003E5__2.Dispose(); } result1 = this.u003Cresultu003E5__1; break; default: this.u003Cclientu003E5__2 = new HttpClient(); goto case 0; } } catch (Exception ex) { this.u003Cu003E1__state = -2; this.u003Cu003Et__builder.SetException(ex); return; } this.u003Cu003E1__state = -2; this.u003Cu003Et__builder.SetResult(result1); } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0) { this.u003Cu003Et__builder.SetStateMachine(param0); } }
  • 28. SynchronizationContext .NET applications have a synchronization context It’s different for each type of app, but fall into buckets  ASP.NET  MVC  WebAPI  WebForms  UI  WPF  WinForms  Windows Store app  Neither  Console app
  • 29. SynchronizationContext suggestions If it’s on the UI or in ASP.NET and you don’t need the context… don’t continue on captured context public async Task<string> GetUrlAsync(string url) { string result = await GetUrlAsync(url, CancellationToken.None).ConfigureAwait(false); return result; }
  • 30. [HttpGet] [Route("getrequesturl")] public async Task<string> GetRequestUrl() { await DoingSomethingAsync().ConfigureAwait(continueOnCapturedContext: false); // And now we're on the thread pool thread without a captured context //so the HttpContext.Current is null //so...UNHANDLED EXCEPTION without compiler warning! return HttpContext.Current.Request.RawUrl; } SynchronizationContext suggestions cont’d But there are places where you do need the context…
  • 31. My rule of thumb:  Don’t use .ConfigureAwait(false) on endpoints and ASP.NET pipeline  MVC controller actions  WebAPI actions  Filters  HttpHandlers  Http Message Handlers like DelegatingHandler  Use .ConfigureAwait(false) basically everywhere else SynchronizationContext suggestions cont’d
  • 32.
  • 34. The Deadlock with .Result or .Wait()  Don’t do .Result or .Wait() on unfinished task  Or at all… [HttpGet] [Route("deadlockdemo")] public string DeadlockDemo() { string urlContent = _httpService.GetUrlAsync("http://finance.yahoo.com").Result; return urlContent; } public async Task<string> GetUrlAsync(string url) { string result = await GetUrlAsync(url, CancellationToken.None); return result; } AspNetSynchronizationContext will ensure that they execute one at a time https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
  • 36. The Deadlock cont’d Remember the SynchronizationContext? [HttpGet] [Route("deadlockdemo")] public async Task<string> DeadlockDemo() { string urlContent = _httpService.GetUrlAsync("http://finance.yahoo.com").Result; return urlContent; } public async Task<string> GetUrlAsync(string url) { string result = await GetUrlAsync(url, CancellationToken.None).ConfigureAwait(false); return result; } If ALL awaited tasks are set to configureawait false, the block won’t cause a deadlock
  • 37. Synchronous Method public string Echo(string message) { return message; } ALSO Synchronous Method public async Task<string> EchoAsync(string message) { return message; } 10x SLOWER!
  • 38. ALSO Synchronous public Task<string> EchoAsync2(string message) { return Task.FromResult(message); } 10x SLOWER! 2.5x SLOWER! public async Task<string> EchoAsync3(string message) { return await Task.FromResult(message); }
  • 39. Asynchronous, but in Parallel public async Task<string> GetUrlAsync2() { string result = await Task.Run(async () => await _httpService.GetUrlAsync("http://blogs.msdn.com/b/pfxteam/") ); return result; } Already an async call, no need for parallel
  • 40. Synchronous as parallel async? [HttpGet] [Route("syncasasync")] public async Task<string> SyncAsParallelAsync() { string retVal = await Task.Run(() => GetUrl("http://blog.stephencleary.com/")); return retVal; }
  • 41. But I need to call an async method synchronously!  IF you can’t change the interface  Can’t change from return of string to return of Task<string> that gets awaited [HttpGet] [Route("asyncassync")] public string AsyncAsSync() { string cachedItem = Task.Run(() => GetFromCacheAsync(CancellationToken.None)).Result; return cachedItem; } Avoid if at all possible!
  • 42. Async void  Avoid async void!  Only use async void if you MUST conform to prior interface.  Primarily for events private async void btnDownload_Click(object sender, RoutedEventArgs e) { btnDownload.IsEnabled = false; try { txtResult.Text = await DownloadStringAsync(txtUrl.Text, new Progress<int>(p => pbDownloadProgress.Value = p)); } finally { btnDownload.IsEnabled = true; } }
  • 43. Async All The Way Once you start, you can’t stop… public static async Task<T> MakeHttpRequestAsync<T>(…) private async Task<TResult> GetHttpAsync<T, TResult>(…) public async Task<TResponse> GetRulesEngineResponseAsync(…) private async Task<SavingsRulesResponse> GetSavingsRulesAsync(…) public async Task<ExperimentTemplate> CallToActionBuilderAsync(…) private Task GenerateCallsToActionAndRespondAsync(…) [System.Web.Http.Route("generatecallstoaction")] [HttpPost] public async Task<ApiResponseActionResult> GenerateCallsToActionAsync(…)
  • 44. Back to the regularly scheduled talk… using System.Threading.Tasks;
  • 45. Cancellations [HttpGet] [Route("geturlsasync")] public async Task<string> GetUrlsAsync() { var watch = Stopwatch.StartNew(); var cts = new CancellationTokenSource(1000); var urlResultsTasks = new List<Task<string>>(); try { urlResultsTasks = Urls.Select(url => _httpService.GetUrlAsync(url, cts.Token)).ToList(); await Task.WhenAll(urlResultsTasks); } catch (TaskCanceledException ex) { //swallow ex for now } return string.Format("Cancelled Tasks: {0} Elapsed Time In MS: {1}", urlResultsTasks.Count(x => x.IsCanceled), watch.ElapsedMilliseconds); } OUTPUT: "Cancelled Tasks: 1 Elapsed Time In MS: 1152"
  • 46. Cancellations cont’d The trickle down effect of cancellation code public async Task<string> GetUrlAsync(string url,CancellationToken cancellationToken) { string result; var uri = new Uri(url); using (var client = new HttpClient()) { cancellationToken.ThrowIfCancellationRequested(); //optional var response = await client.GetAsync(uri, cancellationToken); //network I/O cancellationToken.ThrowIfCancellationRequested(); //optional result = await response.Content.ReadAsStringAsync(); //potentially network I/O } return result; }
  • 47. Cancellations linked [HttpGet] [Route("geturlsasync2")] //[AsyncTimeout(1500)] for MVC only public async Task<string> GetUrlsAsync2(CancellationToken cancellationToken) { var watch = Stopwatch.StartNew(); var cts = new CancellationTokenSource(1000); var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cts.Token); var urlResultsTasks = new List<Task<string>>(); try { urlResultsTasks = Urls.Select(url => _httpService.GetUrlAsync(url, linkedCts.Token)).ToList(); await Task.WhenAll(urlResultsTasks); } catch (TaskCanceledException ex) { //swallow ex for now } return string.Format("Cancelled Tasks: {0} Elapsed Time In MS: {1}", urlResultsTasks.Count(x => x.IsCanceled), watch.ElapsedMilliseconds); }
  • 48. Async lambdas Can use async on Action<T> and Func<T> types [HttpGet] [Route("asynclambda")] public async Task<string> AsyncLambda() { string closureMessage = null; var task = ExecuteAsyncAndLogTime("GetFromCacheAsync", async () => { closureMessage = await GetFromCacheAsync(CancellationToken.None); }); await task; return closureMessage; } private async Task ExecuteAsyncAndLogTime(string title, Func<Task> asyncAction) { var watch = Stopwatch.StartNew(); await asyncAction.Invoke(); Debug.WriteLine("{0} ElapsedTimeInMs: {1}", title, watch.ElapsedMilliseconds); }
  • 49. Async lambdas cont’d The Try Tri! public static async Task<T> DoAsync<T>(Func<Task<T>> action, TimeSpan retryInterval, int retryCount = 3) { var exceptions = new List<Exception>(); for (int retry = 0; retry < retryCount; retry++) { if (retry > 0) { await Task.Delay(retryInterval); } try { return await action(); } catch (Exception ex) { exceptions.Add(ex); } } throw new AggregateException(exceptions); }
  • 50. Task.FromResult [HttpGet] [Route("fromresult")] public async Task<string> FromResult() { string closureMessage = null; var task = ExecuteAsyncAndLogTime("Synchronous",() => { closureMessage = GetText(); return Task.FromResult(0); //.NET 4.6 has Task.CompletedTask for this }); await task; return closureMessage; }
  • 51. Hot and Cold methods  All async tasks run HOT  As soon as task created, method is started (like regular method) [HttpGet] [Route("getfromcache")] public async Task<string> GetFromCache() { var getFromCacheTask = GetFromCacheAsync(CancellationToken.None); SomethingSynchronous(); string cachedItem = await getFromCacheTask; return cachedItem; } Note: GetFromCacheAsync takes 0.5 seconds and SomethingSynchronous takes 1 second Total time was 1.149 seconds
  • 52. Cold Tasks (.NET 4.0) [HttpGet] [Route("coldtask")] public void ColdTask() { var task = new Task(() => { SomethingSynchronous(); // ...and some more stuff }); task.Start(); } If you have a need, could be useful for computationally bound asynchrony, but… You should probably AVOID this
  • 53. Exceptions [HttpGet] [Route("throwerror")] public async Task<string> ThrowErrorAsync() { string message = null; var t = ThrowErrorCoreAsync(); try { message = await t; } catch (Exception ex) { return "ERROR awaiting"; } return message; } private async Task<string> ThrowErrorCoreAsync() { throw new Exception("Error!"); await GetFromDbAsync(CancellationToken.None); } Work basically how you’d expect…
  • 54. Exceptions cont’d Well…almost private async Task GetMultipleErrorsAsync() { var t1 = ThrowErrorCoreAsync(); var t2 = ThrowErrorCoreAsync2(); var t3 = ThrowErrorCoreAsync3(); var tAll = Task.WhenAll(t1, t2, t3); try { await tAll; } catch (Exception ex) { Debugger.Break(); } } Exception thrown is error from t1, but tAll has AggregateException of all 3 errors
  • 55.
  • 56. Aync Http public async Task<string> GetUrlAsync(string url,CancellationToken cancellationToken) { string result; var uri = new Uri(url); using (var client = new HttpClient()) { var response = await client.GetAsync(uri, cancellationToken).ConfigureAwait(false); //network I/O result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); //potentially network I/O } return result; }
  • 58. Service References cont’d public static async Task Foo() { using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client()) { Task<string> t = client.GetDataAsync(1); string result = await t; } }
  • 59. ADO.NET using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); using (SqlCommand command = new SqlCommand(commandString, connection)) { using (SqlDataReader reader = await command.ExecuteReaderAsync()) { //Some code if (await reader.ReadAsync()) { //more code } //Other code } } }
  • 60. Entity Framework 6 public static async Task PerformDatabaseOperations() { using (var db = new BloggingContext()) { // Create a new blog and save it db.Blogs.Add(new Blog { Name = "Test Blog #" + (db.Blogs.Count() + 1) }); Console.WriteLine("Calling SaveChanges."); await db.SaveChangesAsync(); Console.WriteLine("SaveChanges completed."); // Query for all blogs ordered by name Console.WriteLine("Executing query."); var blogs = await (from b in db.Blogs orderby b.Name select b).ToListAsync(); // Write all blogs out to Console Console.WriteLine("Query completed with following results:"); foreach (var blog in blogs) { Console.WriteLine(" - " + blog.Name); } } }
  • 61. EF 6 stored procedure async with Table-Valued Parameter public async Task UpdateSoftOfferEndpointsActiveFlag(Dictionary<string, bool> softOfferEndpointDictionary) { const string sql = "exec [SavingsEngine].[pUpdateSoftOfferEndpointsActiveFlag] @ipSoftOfferEndpointDictionary"; if (softOfferEndpointDictionary == null || !softOfferEndpointDictionary.Any()) { return; } var ipSoftOfferEndpointDictionaryParameter = new SqlParameter("@ipSoftOfferEndpointDictionary", System.Data.SqlDbType.Structured) { TypeName = "SavingsEngine.DictionaryStringBit" }; var temp = new System.Data.DataTable(); temp.Columns.Add("Key", typeof(string)); temp.Columns.Add("Value", typeof(bool)); foreach (var kvp in softOfferEndpointDictionary) { temp.Rows.Add(kvp.Key, kvp.Value); } ipSoftOfferEndpointDictionaryParameter.Value = temp; await _cbasContext.Database.ExecuteSqlCommandAsync(sql, ipSoftOfferEndpointDictionaryParameter).ConfigureAwait(false); }
  • 62. Redis StackExchange.Redis https://github.com/StackExchange/StackExchange.Redis string value = "abcdefg"; await db.StringSetAsync("mykey", value); ... string value = await db.StringGetAsync("mykey"); Console.WriteLine(value); // writes: "abcdefg" public async Task SetRecaptchaCache(ConsumerType model) { string recaptchaHashKey = GetRecaptchaHashKey(model); await m_redis.StringSetAsync(recaptchaHashKey, true, TimeSpan.FromMinutes(10)).ConfigureAwait(false); }
  • 63. MongoDB https://github.com/mongodb/mongo-csharp-driver var client = new MongoClient("mongodb://localhost:27017"); var database = client.GetDatabase("foo"); var collection = database.GetCollection<Person>("bar"); await collection.InsertOneAsync(new Person { Name = "Jack" }); var list = await collection.Find(x => x.Name == "Jack") .ToListAsync(); foreach(var person in list) { Console.WriteLine(person.Name); }
  • 64. Amazon Web Services http://docs.aws.amazon.com/sdkfornet/latest/apidocs/Index.html  Simple Notification Service (SNS)  public virtual Task<PublishResponse> PublishAsync( PublishRequest request, CancellationToken cancellationToken )  Simple Queue Service (SQS)  public virtual Task<SendMessageResponse> SendMessageAsync( SendMessageRequest request, CancellationToken cancellationToken)  Simple Storage Service (S3)  public virtual Task<GetObjectResponse> GetObjectAsync( GetObjectRequest request, CancellationToken cancellationToken )
  • 65. New in .NET 4.6  Not much…  Task.FromException  Task.FromCancelled  Task.CompletedTask  Task{Creation/Continuation}Options.RunContinuationsAsynchronously  Allows you to run .SetResult within a lock  Except…  Now able to await in catch and finally blocks!
  • 66. Conclusion  Code the way you live, asynchronously!  That is, code NETWORK I/O calls asynchronously  But…  Don’t use async on synchronously running code  Test the performance. Is it saving time?
  • 68. Why run this as async? [HttpGet] [Route("geturlasync")] public async Task<string> GetUrlAsync() { string result = await _httpService.GetUrlAsync("http://blogs.msdn.com/b/pfxteam/"); return result; }  There is no thread!  When the thread has no more work to do while awaiting, it goes back to the threadpool  Increased server throughput  Server can process more requests
  • 69. Task.Yield Copied from TAP doc https://www.microsoft.com/en-us/download/details.aspx?id=19957 Task.Run(async delegate { for(int i=0; i<1000000; i++) { await Task.Yield(); // fork the continuation into a separate work item ... } });
  • 70. public static Task<string> DownloadStringAsync(Uri url) { var tcs = new TaskCompletionSource<string>(); var wc = new WebClient(); wc.DownloadStringCompleted += (s,e) => { if (e.Error != null) tcs.TrySetException(e.Error); else if (e.Cancelled) tcs.TrySetCanceled(); else tcs.TrySetResult(e.Result); }; wc.DownloadStringAsync(url); return tcs.Task; } TaskCompletionSource and EAP Copied from TAP doc https://www.microsoft.com/en-us/download/details.aspx?id=19957
  • 71. Meet the experts  Stephen Toub  On Visual Studio Parallel Programming team at Microsoft  http://blogs.msdn.com/b/pfxteam/  Wrote THE document on the TAP  https://www.microsoft.com/en- us/download/details.aspx?id=19957  Speaker at MS Build 2011,2013
  • 72. Meet the experts cont’d  Stephen Cleary  Microsoft MVP  Avid StackOverflow user  Answered my async/await question  Great blog  http://blog.stephencleary.com/  Wrote the book on concurrency  Concurrency in C# Cookbook on Amazon
  • 73. References  The Task-based Asynchronous Pattern  The zen of async: Best practices for best performance  MS Build 2011 video – Stephen Toub  Async in ASP.NET video with Damian Edwards et al.  Async'ing Your Way to a Successful App with .NET  MS Build 2013 video – Stephen Toub  Building parallelized apps with .NET and Visual Studio  MS Build 2011 video – Stephen Toub  Stephen Toub: Task-Based Asynchrony with Async