Friday, April 3, 2015

ASP.NET Async Tips


  • Avoid using background threads in ASP.NET as there are no background threads on servers unlike a WPF or Console application. For the latter, it may be a good idea to keep the async work separate from the main UI thread to avoid locking up the UI. But there is no separate UI thread for Web Applications to lock up! 

  • Doing so gives up the current thread for processing other requests, but you end up taking another thread from the same thread pool, only adding up the cost for a thread swap for no reason. All threads come from the same pool used to serve requests. Moving to another thread just adds cost.

  • If indeed you need a real background thread legitimate reason, consider using SynchronizationContext.Post which can be used in a thread safe manner.

  • Avoid using Task.Wait in ASP.NET like the plague. It is blocking and often causes deadlocks. Deadlocks occur because the framework spins up locks to make thread run thread-safe. But in ASP.NET if blocking using Task.Wait on the same thread it is very easy to cause a deadlock with async code.

  • Avoid Task.ContinueWith as it is not aware of SynchronizationContext and always puts you on a new thread! This has become redundant with await and await is aware of SynchronizationContext is the task does end up running in a separate thread.

  • Be careful with parallelism on the ASP.NET server. Multiple requests * multiple threads can quickly lead to thread starvation for as all threads come from the same pool. Threads consume minimum of 1/4 MB each.

  • However kicking off multiple awaitable async tasks is fine. This actually helps scale your application better as the same thread can serve multiple tasks in an async manner.

  • Don't call fire and forget methods - methods that don't return anything as your void methid code could be terminated anytime the original request ended to return the thread to the thread pool! If needed, use WebBackgrounder from http://nuget.org/packages/webBackgrounder

Check out these references:

Parallel Programming with .NET Blog
http://blogs.msdn.com/pfxteam/

Asynchrony in .NET Whitepaper
http://msdn.com/library/vstudio/hh191443.aspx

ASP.NET Async Tutorial
http://www.asp.net/web-forms/tutorials/aspnet-45/using-asynchronous-methods-in-aspnet-45

Task Parallelism Usage Pattern using Async in ASP.NET

1) Use a list of tasks

var tasks = new List<Task<string>>
{
      CreateHtmlTextFirstAsync(),
      CreateHtmlTextSecondAsync(),
      CreateHtmlTextLastAsync()
};

2) Process tasks if any left in a while loop, removing completed task within the loop.
     Keep flushing out the completed contents of each task as it completes in the loop.
     (Note: Commenting out the check for IsFaulted that would not display content if the task had faulted, as this check may not be correctly coded here)

context.Response.ContentType = "text/html";
context.Response.Write(@"<!DOCTYPE html><html><body>");
context.Response.Write(@"<title>Async Body Sections!</title>");

while (tasks.Any())
{
      var completed = await Task.WhenAny(tasks);
      task.Remove(completed);
   
      //if (!completed.IsFaulted)
      //{
            context.Response.Write(completed.Result);
            context.Response.Flush();
     // }
}

context.Response.Write(@"</body></html>");

**********************************************

We can improve the above code further by making the Response.Flush run asynchronously.
There is no async method for it, but we can make use of Task class like so and make it awaitable:

await Task.Factory.FromAsync(context.Response.BeginFlush, context.Response.EndFlush, null);


Async Cancellation Tokens

ASP.NET has 3 built in Cancellation tokens that allow us to terminate an in-flight async task - say cancel even a database query that is executing. For instance, when the token is marked as Cancel, then ASP.NET terminates the async task to return the thread back to the threadpool.

The three built-in tokens are:

  • RequestTimeout - request timed out so discontinue
  • ClientDisconnected - client closed the browser, so discontinue async work
  • AsyncTimeout - set a timeout for my async task


Note: Always use RegisterAsyncTask when doing async code in ASP.NET. It is a best practice.

Example code snippet on Page_Load of ASP.NET Webforms,

RegisterAsyncTask(new PageAsyncTask(async ()=>
   {
      var token = Response.ClientDisconnectedToken;

       var stockJson = await new HttpClient().GetStringAsync(Constants.StockServiceUri, token);
       var stock = JsonConvert.DeserializeObject<Stock>(stockJson);
       DisplayStock(stock);

       var rssXml = await new HttpClient().GetStringAsync(Constants.RssUri, token);
       var rss = Desserialize(rssXml);
        DisplayRss(rss);
   }));

Note: The GetStringAsync is an extension method you can define as

public static class HttpClientExtensions
{
      public static async Task<string> GetStringAsync(
                 this HttpClient client,
                 string requestUri,
                 CancellationToken token) // this parameter is optional!!
     {
           var response = await client.GetAsync(requestUri, token);
           var result = await response.Content.ReadAsStringAsync();
           return result;
     }
}

**************************************************************************

The Webforms, WebAPI and MVC APIs allow only passing in one token object at a time, so we can wire all three tokens in a single object and pass it in! We can build a composite token this way,

var source = CancellationTokenSource.CreateLinkedTokenSource(
      Response.ClientDisconnectedToken,
      Request.TimedOutToken,
      t); //where t is the AsyncTimeOut token

//Use this composite source object
var token = source.Token;

Make sure to pass in "t" as a parameter to the lambda expression for PageAsyncTask like so

new PageAsyncTask(async (t) =>

*************************************************************************

WebApi and MVC actually makes this simpler by simply taking in a CancellationToken parameter in its method signatures. Also retrospectively adding this parameter does not affect any existing clients that don't pass in this token.

Example WebApi Get,

private StockContext entityDb = new StockContext();

public async Task<Stock> Get(CancellationToken token)
{
     return await entityDb.Stocks.FirstAsync(token);
}

Takeaways:

  1. Cancellation tokens further reduce thread usage and supplement async/await
  2. ASP.NET has built-in Cancellation tokens
  3. Use CancellationTokenSource to combine tokens


Sunday, March 22, 2015

AngularJS 1.x and ReactJS

You've got to love this post on CodeMentor.io comparing Angular 1.x with ReactJS

https://www.codementor.io/reactjs/tutorial/react-vs-angularjs

A lot to find out about ReactJS. Proponents say it is more scalable AND faster using a virtual DOM than Angular with its 2000 $watch limit, but it also re-introduces html mixing with JS! Many would consider that an anti-pattern and not conducive to UI Testing. What about MeteorJS? Is that going to be a better framework? Would Angular 2.0 become the de-facto popular framework come late 2016? Guess, we will all find out in the not too distant future.

Saturday, March 21, 2015

Deadlock Async Await

Avoid using Task.Wait or Task.Result while calling async code as this would block on calling the async code. Any code that blocks on calling async code could cause deadlocks. Example:

public static class DeadlockAsyncTaskWait
{
  private static async Task DelayAsync()
  {
    await Task.Delay(1000);
  }
  
  // This method causes a deadlock when called in a GUI or ASP.NET context.
// Will work just fine when calling from a console app!
  public static void Test()
  {
    // Start the delay.
    var delayTask = DelayAsync();
    
    // Wait for the delay to complete.
    delayTask.Wait();
  }
}

Moral of the story: Go async all the way and use async await. That's just the nature of asynchronous coding

Reference : https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Sunday, March 15, 2015

Of Nullable Type in C#

Nullable Types (they are used for value types) are very useful when dealing with database tables that has a column with NULLABLE value type. Allowing the default value to go through in the ORM or data layer could be misleading becuase NULL could default to the 0 value say for an int type property/column.

So use int? to assign the value of the NULLABLE int column type from the database when mapping to your POCO objects. Since we use a nullable type, we can use HasValue method while mapping the property to try to get to the value.

Nullable types DONT work for reference types like strings or your reference type POCO objects, because they are already NULLABLE (default value is NULL) and the compiler does not allow it. It makes sense, because there is no reason to add NULLABLE type to reference types which are already NULL by default.

So these are not allowed
Player? nullablePlayer;
string? nullableString;


while this is allowed
int? nullableInt; //The default value then is NULL and not 0.

Sunday, November 9, 2014

SQL Coalesce Example

What does this SQL do?

SELECT COALESCE(FirstName + ' ' + MiddleName, FirstName) + ' ' + LastName FROM Customer

If MiddleName is NULL, then FirstName + '' + MiddleName would be NULL, and so would return FirstName + ' ' + LastName.

If MiddleName is not NULL, it would return FirstName + ' ' +MiddleName + ' ' + LastName