Sorted By: Tag (async)

Should I await on Task.FromResult Method Calls?

Task class has a static method called FromResult which returns an already completed (at the RanToCompletion status) Task object. I have seen a few developers "await"ing on Task.FromResult method call and this clearly indicates that there is a misunderstanding here. I'm hoping to clear the air a bit with this post.
2014-02-24 21:14
Tugberk Ugurlu


Task class has a static method called FromResult which returns an already completed (at the RanToCompletion status) Task object. I have seen a few developers "await"ing on Task.FromResult method call and this clearly indicates that there is a misunderstanding here. I'm hoping to clear the air a bit with this post.

What is the use of Task.FromResult method?

Imagine a situation where you are implementing an interface which has the following signature:

public interface IFileManager
{
     Task<IEnumerable<File>> GetFilesAsync();
}

Notice that the method is Task returning which allows you to make the return expression represent an ongoing operation and also allows the consumer of this method to call this method in an asynchronous manner without blocking (of course, if the underlying layer supports it). However, depending on the case, your operation may not be asynchronous. For example, you may just have the files inside an in memory collection and want to return it from there, or you can perform an I/O operation to retrieve the files list asynchronously from a particular data store for the first time and cache the results there so that you can just return it from the in-memory cache for the upcoming calls. These are just some scenarios where you need to return a successfully completed Task object. Here is how you can achieve that without the help of Task.FromResult method:

public class InMemoryFileManager : IFileManager
{
    IEnumerable<File> files = new List<File>
    {
        //...
    };

    public Task<IEnumerable<File>> GetFilesAsync()
    {
        var tcs = new TaskCompletionSource<IEnumerable<File>>();
        tcs.SetResult(files);

        return tcs.Task;
    }
}

We here used the TaskCompletionSource to produce a successfully completed Task object with the result. Therefore, the caller of the method will immediately have the result. This was what we had been doing till the introduction of .NET 4.5. If you are on .NET 4.5 or above, you can just use the Task.FromResult to perform the same operation:

public class InMemoryFileManager : IFileManager
{
    IEnumerable<File> files = new List<File>
    {
        //...
    };

    public Task<IEnumerable<File>> GetFilesAsync()
    {
        return Task.FromResult<IEnumerable<File>>(files);
    }
}

Should I await Task.FromResult method calls?

TL;DR version of the answer: absolutely not! If you find yourself in need to using Task.FromResult, it's clear that you are not performing any asynchronous operation. Therefore, just return the Task from the Task.FromResult output. Is it dangerous to do this? Not completely but it's illogical and has a performance effect.

Long version of the answer is a bit more in depth. Let's first see what happens when you "await" on a method which matches the pattern:

IEnumerable<File> files = await fileManager.GetFilesAsync();

This code will be read by the compiler as follows (well, in a simplest way):

var $awaiter = fileManager.GetFilesAsync().GetAwaiter();
if(!$awaiter.IsCompleted) 
{
     DO THE AWAIT/RETURN AND RESUME
}

var files = $awaiter.GetResult();

Here, we can see that if the awaited Task already completed, then it skips all the await/resume work and directly gets the result. Besides this fact, if you put "async" keyword on a method, a bunch of code (including the state machine) is generated regardless of the fact that you use await keyword inside the method or not. Keeping all these facts in mind, implementing the IFileManager as below is going to cause nothing but overhead:

public class InMemoryFileManager : IFileManager
{
    IEnumerable<File> files = new List<File>
    {
        //...
    };

    public async Task<IEnumerable<File>> GetFilesAsync()
    {
        return await Task.FromResult<IEnumerable<File>>(files);
    }
}

So, don't ever think about "await"ing on Task.FromResult or I'll hunt you down in your sweet dreams :)

References

How and Where Concurrent Asynchronous I/O with ASP.NET Web API

When we have uncorrelated multiple I/O operations that need to be kicked off, we have quite a few ways to fire them off and which way you choose makes a great amount of difference on a .NET server side application. In this post, we will see how we can handle the different approaches in ASP.NET Web API.
2014-02-21 22:06
Tugberk Ugurlu


When we have uncorrelated multiple I/O operations that need to be kicked off, we have quite a few ways to fire them off and which way you choose makes a great amount of difference on a .NET server side application. Pablo Cibraro already has a great post on this topic (await, WhenAll, WaitAll, oh my!!) which I recommend you to check that out. In this article, I would like to touch on a few more points. Let's look at the options one by one. I will use a multiple HTTP request scenario here which will be consumed by an ASP.NET Web API application but this is applicable for any sort of I/O operations (long-running database calls, file system operations, etc.).

We will have two different endpoint which will hit to consume the data:

  • http://localhost:2700/api/cars/cheap
  • http://localhost:2700/api/cars/expensive

As we can infer from the URI, one of them will get us the cheap cars and the other one will get us the expensive ones. I created a separate ASP.NET Web API application to simulate these endpoints. Each one takes more than 500ms to complete and in our target ASP.NET Web API application, we will aggregate these two resources together and return the result. Sounds like a very common scenario.

Inside our target API controller, we have the following initial structure:

public class Car 
{
    public int Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public float Price { get; set; }
}

public class CarsController : BaseController 
{
    private static readonly string[] PayloadSources = new[] { 
        "http://localhost:2700/api/cars/cheap",
        "http://localhost:2700/api/cars/expensive"
    };

    private async Task<IEnumerable<Car>> GetCarsAsync(string uri) 
    {
        using (HttpClient client = new HttpClient()) 
        {
            var response = await client.GetAsync(uri).ConfigureAwait(false);
            var content = await response.Content
                .ReadAsAsync<IEnumerable<Car>>().ConfigureAwait(false);

            return content;
        }
    }

    private IEnumerable<Car> GetCars(string uri) 
    {
        using (WebClient client = new WebClient()) 
        {    
            string carsJson = client.DownloadString(uri);
            IEnumerable<Car> cars = JsonConvert
                .DeserializeObject<IEnumerable<Car>>(carsJson);
                
            return cars;
        }
    }
}

We have a Car class which will represent a car object that we are going to deserialize from the JSON payload. Inside the controller, we have our list of endpoints and two private methods which are responsible to make HTTP GET requests against the specified URI. GetCarsAsync method uses the System.Net.Http.HttpClient class, which has been introduces with .NET 4.5, to make the HTTP calls asynchronously. With the new C# 5.0 asynchronous language features (A.K.A async modifier and await operator), it is pretty straight forward to write the asynchronous code as you can see. Note that we used ConfigureAwait method here by passing the false Boolean value for continueOnCapturedContext parameter. It’s a quite long topic why we need to do this here but briefly, one of our samples, which we are about to go deep into, would introduce deadlock if we didn’t use this method.

To be able to measure the performance, we will use a little utility tool from Apache Benchmarking Tool (A.K.A ab.exe). This comes with Apache Web Server installation but you don’t actually need to install it. When you download the necessary ZIP file for the installation and extract it, you will find the ab.exe inside. Alternatively, you may use Web Capacity Analysis Tool (WCAT) from IIS team. It’s a lightweight HTTP load generation tool primarily designed to measure the performance of a web server within a controlled environment. However, WCAT is a bit hard to grasp and set up. That’s why we used ab.exe here for simple load tests.

Please, note that the below compressions are poor and don't indicate any real benchmarking. These are just compressions for demo purposes and they indicate the points that we are looking for.

Synchronous and not In Parallel

First, we will look at all synchronous and not in parallel version of the code. This operation will block the running the thread for the amount of time which takes to complete two network I/O operations. The code is very simple thanks to LINQ.

[HttpGet]
public IEnumerable<Car> AllCarsSync() {

    IEnumerable<Car> cars =
        PayloadSources.SelectMany(x => GetCars(x));

    return cars;
}

For a single request, we expect this to complete for about a second.

AllCarsSync

The result is not surprising. However, when you have multiple concurrent requests against this endpoint, you will see that the blocking threads will be the bottleneck for your application. The following screenshot shows the 200 requests to this endpoint in 50 requests blocks.

AllCarsSync_200

The result is now worse and we are paying the price for blowing the threads for long running I/O operations. You may think that running these in-parallel will reduce the single request time and you are not wrong but this has its own caveats, which is our next section.

Synchronous and In Parallel

This option is mostly never good for your application. With this option, you will perform the I/O operations in parallel and the request time will be significantly reduced if you try to measure only with one request. However, in our sample case here, you will be consuming two threads instead of one to process the request and you will block both of them while waiting for the HTTP requests to complete. Although this reduces the overall request processing time for a single request, it consumes more resources and you will see that the overall request time increases while your request count increases. Let’s look at the code of the ASP.NET Web API controller action method.

[HttpGet]
public IEnumerable<Car> AllCarsInParallelSync() {

    IEnumerable<Car> cars = PayloadSources.AsParallel()
        .SelectMany(uri => GetCars(uri)).AsEnumerable();

    return cars;
}

We used “Parallel LINQ (PLINQ)” feature of .NET framework here to process the HTTP requests in parallel. As you can, it was just too easy; in fact, it was only one line of digestible code. I tent to see a relationship between the above code and tasty donuts. They all look tasty but they will work as hard as possible to clog our carotid arteries. Same applies to above code: it looks really sweet but can make our server application miserable. How so? Let’s send a request to this endpoint to start seeing how.

AllCarsInParallelSync

As you can see, the overall request time has been reduced in half. This must be good, right? Not completely. As mentioned before, this is going to hurt us if we see too many requests coming to this endpoint. Let’s simulate this with ab.exe and send 200 requests to this endpoint in 50 requests blocks.

AllCarsInParallelSync_200

The overall performance is now significantly reduced. So, where would this type of implementation make sense? If your server application has small number of users (for example, an HTTP API which consumed by the internal applications within your small team), this type of implementation may give benefits. However, as it’s now annoyingly simple to write asynchronous code with built-in language features, I’d suggest you to choose our last option here: “Asynchronous and In Parallel (In a Non-Blocking Fashion)”.

Asynchronous and not In Parallel

Here, we won’t introduce any concurrent operations and we will go through each request one by one but in an asynchronous manner so that the processing thread will be freed up during the dead waiting period.

[HttpGet]
public async Task<IEnumerable<Car>> AllCarsAsync() {

    List<Car> carsResult = new List<Car>();
    foreach (var uri in PayloadSources) {

        IEnumerable<Car> cars = await GetCarsAsync(uri);
        carsResult.AddRange(cars);
    }

    return carsResult;
}

What we do here is quite simple: we are iterating through the URI array and making the asynchronous HTTP call for each one. Notice that we were able to use the await keyword inside the foreach loop. This is all fine. The compiler will do the right thing and handle this for us. One thing to keep in mind here is that the asynchronous operations won’t run in parallel here. So, we won’t see a difference when we send a single request to this endpoint as we are going through the each request one by one.

AllCarsAsync

As expected, it took around a second. When we increase the number of requests and concurrency level, we will see that the average request time still stays around a second to perform.

AllCarsAsync_200

This option is certainly better than the previous ones. However, we can still do better in some certain cases where we have limited number of concurrent I/O operations. The last option will look into this solution but before moving onto that, we will look at one other option which should be avoided where possible.

Asynchronous and In Parallel (In a Blocking Fashion)

Among these options shown here, this is the worst one that one can choose. When we have multiple Task returning asynchronous methods in our hand, we can wait all of them to finish with WaitAll static method on Task object. This results several overheads: you will be consuming the asynchronous operations in a blocking fashion and if these asynchronous methods is not implemented right, you will end up with deadlocks. At the beginning of this article, we have pointed out the usage of ConfigureAwait method. This was for preventing the deadlocks here. You can learn more about this from the following blog post: Asynchronous .NET Client Libraries for Your HTTP API and Awareness of async/await's Bad Effects.

Let’s look at the code:

[HttpGet]
public IEnumerable<Car> AllCarsInParallelBlockingAsync() {
    
    IEnumerable<Task<IEnumerable<Car>>> allTasks = 
        PayloadSources.Select(uri => GetCarsAsync(uri));

    Task.WaitAll(allTasks.ToArray());
    return allTasks.SelectMany(task => task.Result);
}

Let's send a request to this endpoint to see how it performs:

AllCarsInParallelBlockingAsync

It performed really bad but it gets worse as soon as you increase the concurrency rate:

AllCarsInParallelBlockingAsync_200

Never, ever think about implementing this solution. No further discussion is needed here in my opinion.

Asynchronous and In Parallel (In a Non-Blocking Fashion)

Finally, the best solution: Asynchronous and In Parallel (In a Non-Blocking Fashion). The below code snippet indicates it all but just to go through it quickly, we are bundling the Tasks together and await on the Task.WhenAll utility method. This will perform the operations asynchronously in Parallel.

[HttpGet]
public async Task<IEnumerable<Car>> AllCarsInParallelNonBlockingAsync() {

    IEnumerable<Task<IEnumerable<Car>>> allTasks = PayloadSources.Select(uri => GetCarsAsync(uri));
    IEnumerable<Car>[] allResults = await Task.WhenAll(allTasks);

    return allResults.SelectMany(cars => cars);
}

If we make a request to the endpoint to execute this piece of code, the result will be similar to the previous one:

AllCarsInParallelNonBlockingAsync

However, when we make 50 concurrent requests 4 times, the result will shine and lays out the advantages of asynchronous I/O handling:

AllCarsInParallelNonBlockingAsync_200

Conclusion

At the very basic level, what we can get out from this article is this: do perform load tests against your server applications based on your estimated consumption rates if you have any sort of multiple I/O operations. Two of the above options are what you would want in case of multiple I/O operations. One of them is "Asynchronous but not In Parallel", which is the safest option in my personal opinion, and the other is "Asynchronous and In Parallel (In a Non-Blocking Fashion)". The latter option significantly reduces the request time depending on the hardware and number of I/O operations you have but as our small benchmarking results showed, it may not be a good fit to process a request many concurrent I/O asynchronous operations in one just to reduce a single request time. The result we would see will most probably be different under high load.

References

Sides and Source Code for DEU Bilgisayar Topluluğu Izmir 2. Teknoloji Zirvesi

This weekend, I participated in an event as a speaker in Izmir, DEU Bilgisayar Topluluğu Izmir 2. Teknoloji Zirvesi. Sides and Source Code for my sessions are available.
2013-01-08 04:34
Tugberk Ugurlu


This weekend, I participated in an event as a speaker in Izmir. I also had the chance to meet Fatih Boy, İkay İlknur, Umut Erkal and Oğuzhan Yılmaz at the event. There were great sessions throughout the first and second day.

A_2F067CMAA2b2FA_2Gty6CIAAOKnf

A_2oQg4CcAERiYOA_2XVl7CUAEjVF9

I gave two talks during the event and one of them was on Git and GitHub. You can see the slides for that session below:

At the second day, I talked about asynchronous programming for .NET server applications. Slides for that session is also available on my SpeakerDeck page. You can also get the source code for the demos: https://github.com/tugberkugurlu/IzmirDEU201301ServerSideAsync.

List of Resources on Asynchronous Programming for .NET Server Applications with C#

I listed some resources on asynchronous programming for .NET server applications with C# which consist of blog posts, presentations and podcasts.
2013-01-05 22:01
Tugberk Ugurlu


I will be participating on an event today in Izmir talking about asynchrony for .NET server applications (mostly ASP.NET) and I thought it would be great to list some reference blog posts, presentations and podcasts on this topic as there are a few distinct resources regarding asynchrony as I listed below.

In my talk, I plan to mix some stuff from previous @StevenSanderson, @DamianEdwards, @LeviBroderick, @bradwilson presentations and blog posts. I have also bunch of demos which I will be sharing online in my GitHub repository. So, enjoy the resources for now Winking smile

Resources for Asynchrony in General

Resources for Asynchrony for Server Applications

Why am I not Using NancyFx Instead of ASP.NET MVC / Web API

Why am I not using NancyFx instead of ASP.NET MVC / Web API? Because of a very important and vital missing part with NancyFx: asynchrony!
2012-12-18 19:50
Tugberk Ugurlu


Note: If you don't understand asynchrony and its benefits, you are better off without this blog post. If you are willing to learn the importance of asynchrony for server applications, here are two videos for you to start:

Update 2013-10-08:

Great news! NancyFx now has asyncronous processing ability. See Jonathan Channon's post for more details: Async Route Handling with Nancy 

Server side .NET ecosystem is not just about the frameworks that Microsoft builds and ships such as ASP.NET MVC, ASP.NET Web API, etc. There are other open source frameworks out there such as NancyFx which has been embraced by the community. I haven’t played with NancyFx that much but I really wanted to understand how it is more special than its equivalent frameworks. As far as I can tell, it’s not but I am nowhere near to make that judgment because I only spared 10 minutes to figure that out, which is obviously not enough to judge a framework. Why and where did I stop? Let’s get to that later.

You may have also noticed that I have been kind of opinionated about ASP.NET Web API lately. It’s not because I am writing a book on ASP.NET Web API. The reason of my passion is related to fact that I know how it works internally and I can see that none of the other equivalent frameworks hasn’t been able to get asynchrony right as this framework did (SignalR also gets asynchrony right but it’s kind of a different area)! Please do inform me and make me happy if you think that there is any other framework which we can put under this category. I didn’t put ASP.NET MVC under this category either because it’s not possible to go fully asynchronous throughout the pipeline with ASP.NET MVC. However, it’s has a really nice asynchronous support for most of the cases.

I’m not going to get into the details of how asynchrony is important for a server application because I have tried to do that several times. Let’s stick with the topic: why am I not using NancyFx instead of ASP.NET MVC / Web API? Don’t get me wrong here. NancyFx is a great framework as far as I can see and I’m all supportive for any .NET open source project which makes it easy to get our job done. @TheCodeJunkie and the other NancyFx members have been doing a great job on maintaining this awesome open source framework. However, there is a very important missing part with this framework and it’s vital to any server application: asynchrony! We are now about to see why this is important.

I have created two applications which do the same thing in a different way: downloading the data over HTTP and return it back as a text. I used NancyFx to create one of these applications and this application will make the HTTP call synchronously because there is no way to do it asynchronously with NancyFx. The other application has been implemented using ASP.NET Web API and the only difference will be that it will make the HTTP call asynchronously.

It’s fairly straight forward to get started with NancyFx. I jumped to one of the framework’s documentation page and I was good to go by installing the NuGet package and adding the following module. It was a nice and quick start.

public class HelloModule : NancyModule {

    public HelloModule() {

        Get["/"] = (p) => {

            using (var client = new WebClient()) {
                var textData = client.DownloadString("http://localhost:52907/api/cars");
                return textData;
            }
        };
    }
}

I used WebClient on both applications here because HttpClient has no synchronous methods and making blocking calls with HttpClient has some overheads. I also created an ASP.NET Web API application which does the same thing but asynchronously.

public class DefaultController : ApiController {

    public async Task<string> Get() {

        using (var client = new WebClient()) {

            var textData = await client.DownloadStringTaskAsync(
                "http://localhost:52907/api/cars");

            return textData;
        }
    }
}

As you can see, it’s extremely easy to write asynchronous code with the ".NET 4.5 + C# 5.0 + ASP.NET Web API" combination. You probably noticed that I am making a call against http://localhost:52907/api/cars. This is a simple HTTP API which takes minimum 500 milliseconds to return. This wait is is on purpose to simulate a a-bit-long-running call. Let me also be clear on why I’ve chosen to make a comparison by making an HTTP call. This really doesn’t matter here. Any type of I/O operation could have been a perfect case here but an HTTP call scenario is simple to demonstrate.

Finally, I now have an endpoint on http://localhost:47835 for NancyFx application and another on http://localhost:49167 for ASP.NET Web API application. I have opened up a command line console and get the ab.exe (Apache HTTP Server Benchmarking Tool) under my path. When I generate a request for each one (only one request), I will have a result which is similar to the below screenshot (NancyFx is the lest side, ASP.NET Web API is the right side).

image

Notice that both have taken approx. the same amount of time to complete the request but this’s not the place where asynchrony shines. Let’s now generate totally 200 request (30 concurrent requests at a time) to each endpoint and see the result (NancyFx is the lest side, ASP.NET Web API is the right side).

image

15.31 requests per second with NancyFx + synchronous processing and 49.35 requests per second with ASP.NET Web API + asynchronous processing. Besides the fact that this’s totally an on-the-fly benchmarking (I’m not even sure whether we can call this a benchmark) on my Windows 8 machine, the result is pretty compelling.

Let’s now have a look at the reason why I stopped discovering NancyFx further. Go to NancyFx GitHub repository and navigate to Nancy.Hosting.Aspnet.NancyHttpRequestHandler class file. This is located under the ASP.NET host project for NancyFx and actually the HTTP handler the framework uses to process requests. Earlier today I tweeted after I had a look at this class:

image

Yes, it’s sitting right there. By exposing the framework with a normal handler implementation instead of the IHttpAsyncHandler implementation, you are making your ASP.NET framework suffer. It’s possible for you to handle synchronous calls with an asynchronous handler but it’s impossible (or either not right and easy) to do this with a normal handler. On the other hand, we know that NancyFx doesn’t only have an ASP.NET host option. You can even host this framework under katana with its OWIN Host implementation but it’s not going to matter unless the framework itself has asynchronous processing capabilities and by looking at the above handler and this issue, I can see that it doesn’t have that.

This is not an I-hate-you-and-I-will-stay-that-way-forever-please-go-the-hell-away blog post. Again: NancyFx is a great project and it deserves a good amount of respect. However, this post explains my reason on why I am not using NancyFx instead of ASP.NET Web API or ASP.NET MVC. Will it going to change? Unless #148 is not fixed, it is certainly not. Even if it is fixed, I already have applications running on ASP.NET Web API and ASP.NET MVC. Why bother then? We will see that in the future.

Tags