0% found this document useful (0 votes)
6 views65 pages

C# Async Programming: Common Pitfalls

This document discusses asynchronous programming in C#, focusing on the use of async and await keywords, their benefits, and common pitfalls. It highlights the importance of avoiding async void signatures, managing deadlocks, and the implications of context switching in UI and web applications. Additionally, it mentions planned features for C# 7, including support for async Main and performance improvements with ValueTask<T>.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views65 pages

C# Async Programming: Common Pitfalls

This document discusses asynchronous programming in C#, focusing on the use of async and await keywords, their benefits, and common pitfalls. It highlights the importance of avoiding async void signatures, managing deadlocks, and the implications of context switching in UI and web applications. Additionally, it mentions planned features for C# 7, including support for async Main and performance improvements with ValueTask<T>.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Asynchronous Programming

[Link] vs Asynchronous Programming vs Threading

Task vs Thread

What happens when Wait is called

What happens when ConfigureWait is called

Wait vs ConfigureWait

Tidbits

1. When you use async void as return type, you do not have to use await keyword while calling it
from calling method
2. you could try synchronously waiting for the asynchronous method to complete, by calling Wait on
the returned Task, or reading its Result property

The async and await keywords have been a part of C# language since version 5.0, which was released in
autumn 2013 as part of Visual Studio 2013. Although in essence they make asynchronous
programming simpler, one can still use them incorrectly.

This article describes some of these common mistakes, and gives advice on how to avoid them.

Threading

Threading vs Asynchronous Programming

The Basics of C# Async and Await

As users, we prefer applications which respond quickly to our interactions, and do not “freeze” when
loading or processing data.

While it might still be acceptable for legacy desktop line of business applications to stop responding
occasionally, we are less patient with mobile applications that keep us waiting. Even operating systems
are becoming more responsive, and give you the option to terminate such misbehaving processes.
Figure 1: Windows warns about applications that stopped responding

If you have been a developer for a while, it is very likely that you faced scenarios where your application
became unresponsive. One such example is a data retrieval operation that usually completes in a few
hundred milliseconds at the most, suddenly took several seconds because of server or network
connectivity issues. Since the call was synchronous, the application did not respond to any user
interaction during that time.

To understand why this happens, we must take a closer look at how the operating system communicates
with applications. Whenever the OS needs to notify the application of something, be it the user clicking a
button or wanting to close the application; it sends a message with all the information describing the
action to the application. These messages are stored in a queue, waiting for the application to process
them and react accordingly.

Each application with a graphical user interface (GUI) has a main message loop which continuously
checks the contents of this queue. If there are any unprocessed messages in the queue, it takes out the
first one and processes it. In a higher-level language such as C#, this usually results in invoking a
corresponding event handler. The code in the event handler executes synchronously. Until it completes,
none of the other messages in the queue are processed. If it takes too long, the application will appear to
stop responding to user interaction.

Asynchronous programming using async and await keywords provides a simple way to avoid this
problem with minimal code changes. For example, the following event handler synchronously downloads
an HTTP resource:

private void OnRequestDownload(object sender, RoutedEventArgs e)


{
var request = [Link](_requestedUri);
var response = [Link]();
// process the response
}

Here is an asynchronous version of the same code:


private async void OnRequestDownload(object sender, RoutedEventArgs e)
{
var request = [Link](_requestedUri);
var response = await [Link]();
// process the response
}
Only three changes were required:

- The method signature changed from void to async void, indicating that the method is asynchronous,
allowing us to use the await keyword in its body.

- Instead of calling the synchronous GetResponse method, we are calling the


asynchronous GetResponseAsync method. By convention, asynchronous method names usually have
the Async postfix.

- We added the await keyword before the asynchronous method call. This changes the behavior of the
event handler. Only a part of the method up to the GetResponseAsync call, executes synchronously. At
that point, the execution of the event handler pauses and the application returns to processing the
messages from the queue.

Meanwhile, the download operation continues in the background. Once it completes, it posts a new
message to the queue. When the message loop processes it, the execution of the event handler method
resumes from the GetResponseAsync call. First, its result of type Task<WebResponse> is unwrapped
to WebResponse and assigned to the response variable. Then, the rest of the method executes as
expected. The compiler generates all the necessary plumbing code for this to work.

Although Web applications on the server do not require their own special UI thread, they can still benefit
from asynchronous programming. A dedicated thread processes each incoming request. While this thread
is busy with one request, it cannot start processing another one. Since there is a limited number of
threads available in the thread pool, this limits the number of requests that can be processed in parallel.
Any thread waiting for an I/O operation to complete, is therefore a wasted resource. If the I/O operation is
performed asynchronously instead, the thread is not required any more until the operation completes, and
is released back to the thread pool, making it available to process other requests. Although this might
slightly increase the latency of a single request, it will improve the overall throughput of the application.

The use of async and await keywords is not limited to asynchronous programming though. With Task
Parallel Library (TPL) you can offload CPU intensive operations onto a separate thread by
calling [Link]. You can await the returned task the same way as you would with an asynchronous
method to prevent blocking the UI thread. Unlike real asynchronous operations, the offloaded work still
consumes a thread; therefore, this strategy is not as useful in web applications where there is no special
thread to keep available.

Latency indicates how long it takes for packets to reach their destination.

Throughput is the term given to the number of packets that are processed within a specific period of time

C# Async Await Asynchronous Programming - Common Pitfalls

The async and await keywords provide a great benefit to C# developers by making asynchronous
programming easier. Most of the times, one can use them without having to understand the inner
workings in detail. At least, as long as the compiler is a good enough validator, the code will behave as
intended. However, there are cases when incorrectly written asynchronous code will compile successfully,
but still introduce subtle bugs that can be hard to troubleshoot and fix.

Let us look at some of the most common pitfall examples.

Avoid Using Async Void

The signature of our asynchronous method in the code example we just saw was async void.

While this is appropriate for an event handler and the only way to write one, you should avoid this
signature in all other cases. Instead, you should use async Task or async Task<T> whenever possible,
where T is the return type of your method.

As explained in the previous example, we need to call all asynchronous methods using the await
keyword, e.g.:

DoSomeStuff(); // synchronous method


await DoSomeLengthyStuffAsync(); // long-running asynchronous method
DoSomeMoreStuff(); // another synchronous method

This allows the compiler to split the calling method at the point of the await keyword. The first part ends
with the asynchronous method call; the second part starts with using its result if any, and continues from
there on.

In order to use the await keyword on a method; its return type must be Task. This allows the compiler to
trigger the continuation of our method, once the task completes. In other words, this will work as long as
the asynchronous method’s signature is async Task. Had the signature been async void instead, we
would have to call it without the await keyword:

DoSomeStuff(); // synchronous method


DoSomeLengthyStuffAsync(); // long-running asynchronous method
DoSomeMoreStuff(); // another synchronous method

The compiler would not complain though. Depending on the side effects of DoSomeLengthyStuffAsync,
the code might even work correctly. However, there is one important difference between the two
examples.

In the first one, DoSomeMoreStuff will only be invoked after DoSomeLengthyStuffAsync completes. In
the second one, DoSomeMoreStuff will be invoked immediately after DoSomeLengthyStuffAsync
starts. Since in the latter case DoSomeLengthyStuffAsync and DoSomeMoreStuff run in parallel, race
conditions might occur.

If DoSomeMoreStuff depends on any of DoSomeLengthyStuffAsync’s side effects, these might or


might not yet be available when DoSomeMoreStuff wants to use them. Such a bug can be difficult to fix,
because it cannot be reproduced reliably. It can also occur only in production environment, where I/O
operations are usually slower than in development environment.

To avoid such issues altogether, always use async Task as the signature for methods you intend to call
from your code. Restrict the usage of async void signature to event handlers, which are not allowed to
return anything, and make sure you never call them yourself. If you need to reuse the code in an event
handler, refactor it into a separate method returning Task, and call that new method from both the event
handler and your method, using await.

Beware of Deadlocks

In a way, asynchronous methods behave contagiously. To call an asynchronous method with await, you
must make the calling method asynchronous as well, even if it was not async before. Now, all methods
calling this newly asynchronous method must also become asynchronous. This pattern repeats itself up
the call stack until it finally reaches the entry points, e.g. event handlers.

When one of the methods on this path to the entry points cannot be asynchronous, this poses a problem.
For example, constructors. They cannot be asynchronous, therefore you cannot use await in their body.
As discussed in the previous section, you could break the asynchronous requirement early by giving a
method async void signature, but this prevents you from waiting for its execution to end, which makes it a
bad idea in most cases.

Alternatively, you could try synchronously waiting for the asynchronous method to complete, by
calling Wait on the returned Task, or reading its Result property. Of course, this synchronous code will
temporarily stop your application from processing the message queue, which we wanted to avoid in the
first place. Even worse, in some cases you could cause a deadlock in your application with some very
innocent looking code:

private async void MyEventHandler(object sender, RoutedEventArgs e)


{
var instance = new InnocentLookingClass();
// further code
}
Any synchronously called asynchronous code in InnocentLookingClass constructor is enough to cause a
deadlock:

public class InnocentLookingClass()


{
public InnocentLookingClass()
{
DoSomeLengthyStuffAsync().Wait();
// do some more stuff
}

private async Task DoSomeLengthyStuffAsync()


{
await SomeOtherLengthyStuffAsync();
}

// other class members

Let us dissect what is happening in this code.

MyEventHandler synchronously calls InnocentLookingClass constructor,which


invokes DoSomeLengthyStuffAsync, which in turn asynchronously
invokes SomeOtherLengthyStuffAsync. The execution of the latter method starts; at the same time the
main thread blocks at Wait until DoSomeLengthyStuffAsync completes without giving control back to
the main message loop.

Eventually SomeOtherLengthyStuffAsync completes and posts a message to the message queue


implying that the execution of DoSomeLengthyStuffAsync can continue. Unfortunately, the main thread
is waiting for that method to complete instead of processing the messages, and will therefore never
trigger it to continue, hence waiting indefinitely.

As you can see, synchronously invoking asynchronous methods can quickly have undesired
consequences. Avoid it at all costs; unless you are sure what you are doing, i.e. you are not blocking the
main message loop.

Allow Continuation on a Different Thread

The deadlock in the above example would not happen if DoSomeLengthyStuffAsync did not require to
continue on the main thread where it was running before the asynchronous call. In this case, it would not
matter that this thread was busy waiting for it to complete, and the execution could continue on another
thread. Once completed, the constructor execution could continue as well.

As it turns out, there is a way to achieve this when awaiting asynchronous calls – by
invoking ConfigureAwait(false) on the returned Task before awaiting it:

await SomeOtherLengthyStuffAsync().ConfigureAwait(false);

This modification would avoid the deadlock, although the problem of the synchronous call in the
constructor, blocking the message loop until it completes, would remain.

While allowing continuation on a different thread in the above example might not be the best approach,
there are scenarios in which it makes perfect sense. Switching the execution context back to the
originating thread affects performance, and as long as you are sure that none of the code after it resumes
needs to run on that thread, disabling the context switch will make your code run faster.

You might wonder which code requires the context to be restored. This depends on the type of the
application:

· For user interface based applications (Windows Forms, WPF and UWP), this is required for any code
that interacts with user interface components.
· For web applications ([Link]), this is required for any code accessing the request context or
authentication information.

When you are unsure, you can use the following rule of thumb, which works fine in most cases:

· Code in reusable class libraries can safely disable context restoration.

· Application code should keep the default continuation on the originating thread – just to be on the safer
side.

Planned Features for C# 7

The language designers succeeded in making async and await very useful with its first release in 2013.
Nevertheless, they are constantly paying attention to developer feedback, and try to improve the
experience wherever and whenever it makes sense.

For example, in C# 6.0 (released with Visual Studio 2015) they added support for using await
inside catch and finally blocks. This made it easier and less error prone to use asynchronous methods in
error handling code.

According to plans (which might however still change), C# 7 will have two new features related to
asynchronous programming.

Note: For those new to C# 7, make sure to check out C# 7 – Expected Features

Support for Async Main

In the section about deadlocks, I explained how making a method asynchronous has a tendency of
propagating all the way to their entry points. This works out fine for event driven frameworks (such as
Windows Forms and WPF) because event handlers can safely use async void signature, and for
[Link] MVC applications, which support asynchronous action methods.

If you want to use asynchronous methods from a simple console application, you are on your own. Main
method as the entry point for console applications must not be asynchronous. Hence to call
asynchronous methods in a console application, you need to create your own top-level asynchronous
wrapper method and call it synchronously from Main:

static void Main()


{
MainAsync().Wait();
}
Since there is no message loop to block in a console application, this code is safe to use without the
danger of causing a deadlock.

Language designers are considering the idea of adding support for asynchronous entry points for console
applications, directly into the compiler. This would make any of the following method signatures valid
entry points for console applications in C# 7:
// current valid entry point signatures

void Main()

int Main()

void Main(string[])

int Main(string[])

// proposed additional valid entry point signatures in C# 7

async Task Main()

async Task<int> Main()

async Task Main(string[])

async Task<int> Main(string[])

While this feature might not enable anything that is not already possible, it will reduce the amount of
boilerplate code and make it easier for beginners to call asynchronous methods correctly from console
applications.

Performance Improvements

I have already discussed the impact of context switching on asynchronous programming with async and
await. Another important aspect are memory allocations.

Each asynchronous method allocates up to three objects on the heap:

 the state machine with method’s local variables,


 the delegate to be called on continuation, and
 the returned Task.

Since additional object allocations boils down to more work for the garbage collector, the current
implementation is already highly optimized. The first two allocations only happen when they are required,
i.e. when another asynchronous method is actually awaited. E.g. this scenario would only occur to the
following method when called with true:

private async Task DoSomeWorkAsync(bool doRealWork)


{
if (doRealWork)
{
await DoSomeRealWorkAsync();
}
}
This is a contrived example, but even real-world methods often include edge cases with different
execution paths, which might skip all asynchronous calls in them.

The allocation of the returned task is also already somewhat optimized. Common Task objects (for values
0, 1, true, false, etc.) are cached to avoid allocating a new one whenever one of these commonly used
values are returned.

C# 7 promises to bring this optimization a step further. Asynchronous methods returning value types will
be able to return ValueTask<T> instead of Task<T>. As the name implies,
unlike Task<T>, ValueTask<T> is itself a struct, i.e. a value type that will be allocated on the stack
instead of on the heap. This will avoid any heap allocations whatsoever for asynchronous methods
returning value types, when they make no further asynchronous calls.

Apart from the benefit for garbage collection, initial tests by the team also show almost 50% less time
overhead for asynchronous method invocations, as stated in the feature proposal on GitHub. When
used in tight loops, all of this can add up to significant performance improvements.

Conclusion:

Even though asynchronous programming with C# async and await seems simple enough once you get
used to it, there are still pitfalls to be aware of. The most common one is improper use of async void,
which you can easily overlook and the compiler will not warn you about it either. This can introduce subtle
and hard to reproduce bugs in your code that will cost you a lot of time to fix. If being aware of that
remains your only takeaway from this article, you have already benefited. Of course, learning about the
other topics discussed in this article, will make you an even better developer.

This article has been editorially reviewed by Suprotim Agarwal.


C# and .NET have been around for a very long time, but their constant growth means there’s always
more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C#


and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi
(Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C#
and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core
3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing
knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your
next .NET Interview.

Reference:

Asynchronous Programming in C# using Async Await – Best Practices | DotNetCurry


C# Asynchronous Programming -
Async and Await
What is asynchronous technique?
If you are a senior web developer (at least 5+ years in this field) then you have a lot of experience with
the bad response time of web applications. Yes, there was no way to change a small portion of the
content without reloading the entire page (the situation is more pathetic with a slow internet connection).
But in modern days, the situation has changed. We can do everything (yes, almost everything) without
reloading an entire page or without touching another element. Hence the user's experience and
performance have increased. So, how is it done? You are thinking, with AJAX, right? Yes with AJAX,
simply one asynchronous technique is needed to exchange data between the server and the client. So
the ultimate goal of AJAX is to call a server method and exchange data from the server without
hampering the client. The clients need not wait for the server's response.

So, asynchronous programming is also all about improvement of performance. Basically, we can
implement Ajax in two ways (in [Link]). The first option is by updating the panel and Ajax toolkit and
the second option is by the jQuery Ajax method. (Let's ignore the various third-party JavaScript libraries).
In C# 5.0 Microsoft has given us the ability to write our own asynchronous code with C#. Before starting
with an example I would like to discuss two master keywords of asynchronous programming, called
async and await.

So, let's start.

Async

This keyword is used to qualify a function as an asynchronous function. In other words, if we specify the
async keyword in front of a function then we can call this function asynchronously. Have a look at the
syntax of the asynchronous method.

public async void CallProcess()


{
}

Here the callProcess() method is declared as an asynchronous method because we have declared the
async keyword in front of it. Now it's ready to be called asynchronously.

Await

Very similar to wait, right? Yes, this keyword is used when we want to call any function asynchronously.
Have a look at the following example to understand how to use the await keyword.

Let's think in the following, we have defined a long-running process.

public static Task LongProcess()


{
return [Link](() =>
{
[Link](5000);
});
}
Now, we want to call this long process asynchronously. Here we will use the await keyword.

await LongProcess();

If you're relatively new to the concept of asynchronous programming then this dry definition is not enough
to understand those concepts. So, let's go through one small example and try to understand those
concepts.

Let's create a Windows application and write the following code for it. Here we have created the
LongTask() function that will wait for five minutes. Have a look at the function signature; we have declared
this function with the async keyword. In other words, we can call it asynchronously.

using System;
using [Link];
using [Link];
using [Link];

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static Task LongProcess()
{
Return [Link](() =>
{
[Link](5000);
});
}

public async void CallProcess()


{
await LongProcess();
[Link]("Long Process finish");
}

private void Form1_Load(object sender, EventArgs e)


{
}

private async void button1_Click(object sender, EventArgs e)


{
CallProcess();
[Link]("Program finish");
}
}
}
Here is the sample output.

The return type of an asynchronous function is Task. In other words, when it finishes its execution it will
complete a Task. Each and every asynchronous method can return three types of values.

Void: Means nothing to return

Task: It will perform one operation, a little similar to void but the difference is there.

Task<T>: Will return a task with a T type parameter. (I hope you are familiar with the concept of T)

Let's clarify a few more concepts here:

 The Main method cannot be defined as asynchronous.


 It (the Main method) cannot be invoked by the await keyword.
 If any asynchronous method is not invoked by the await keyword then by nature it will behave like
the synchronous method.
 Function properties should not be defined as asynchronous.
 The await keyword may not be inside a "lock" section.
 A try/catch block should not call any asynchronous methods from the catch or finally block.
 A class constructor or destructor should not define an asynchronous method nor should it be
called asynchronously.
C# Asynchronous Programming -
Return Type of Asynchronous
Method
Asynchronous programming in C# 5.0: Part-1: Understand async and await

In this article, we will understand the various return types of asynchronous functions. In our previous
article, we saw that there are three return types of any asynchronous function. They are:

1. Void
2. Task
3. Task<T>

Oh, you don't see any difference between Task and Task<T>, right? Then that means there are two
return types of asynchronous functions. Let's discuss each of them one by one.

Return void from asynchronous method

Though it's not recommended to return void from an asynchronous function, we can return void
theoretically. Now, the question is, why is it not recommended to return void? The answer is if we return
void then the caller function will not be informed of the completion of the asynchronous function. OK, then
in which scenario can we return void? When we want to call an asynchronous function from an event (like
a button click) then we can specify void in the event.

Let's see that in action:

using System;
using [Link];
using [Link];
using [Link];

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public static Task LongProcess()


{
Return [Link](() =>
{
[Link](5000);
});
}

public async void CallProcess()


{
await LongProcess();
[Link]("Long Process finish");
}

private void Form1_Load(object sender, EventArgs e)


{
}

private void button1_Click(object sender, EventArgs e)


{
[Link] = "Return Void";
CallProcess();
[Link]("Program Finish");
}
}
}
Now, one condition is when we want to return void. We cannot use the await keyword when we want to
return void from an asynchronous function.

In the above example, CallProcess() is an asynchronous function and it's returning void. In the button's
click event, we are calling the CallProcess() function using the await keyword (in other words
asynchronously). The compiler complains.

Return Task from asynchronous method

Let's see how to return a task from an asynchronous method. Basically the returning task is nothing but
sending one signal to the caller function that the task has finished. When a method returns a task, we can
use the await keyword to call it.

Note: The await keyword should be within a function qualified by an async keyword (in other words
asynchronous), otherwise the compiler will treat it as a normal synchronous function.

Have a look at the following code:

using System;
using [Link];
using [Link];
using [Link];

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Task LongProcess()
{
return [Link](() => {
[Link](5000);
});
}
public async Task CallProcess()
{
await LongProcess();
[Link]("Long Finish");
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
[Link] = "Return Task";
CallProcess();
[Link]("Program Finish");
}
}
}

Here we are returning a task from the LongProcess() function so that we can call it using the await
keyword.

Return Task<T> from asynchronous method

Now, let's see how to return Task<T> from an asynchronous method. I hope all of you understand the
meaning of T. Cool! We will return a String from an asynchronous function. Look at the following code:

1. using System;
2. using [Link];
3. using [Link];
4. using [Link];
5.

6. namespace WindowsFormsApplication1
7. {
8. public partial class Form1 : Form
9. {
10. public Form1()
11. {
12. InitializeComponent();
13. }
14. public static Task<string> LongProcess()
15. {
16. return [Link](() =>
17. {
18. [Link](5000);
19. return "Long Process Finish";
20. });
21. }
22. public async void CallProcess()
23. {
24. String Value = await LongProcess();
25. [Link](Value);
26. }
27. private void Form1_Load(object sender, EventArgs
e)
28. {
29. }
30. private async void button1_Click(object sender, E
ventArgs e)
31. {
32. [Link] = "Return Task<T>";
33. CallProcess();
34. [Link]("Program Finish");
35. }
36. }
37. }
From the LongProcess() we are returning a string to the CallProcess() function.

Conclusion

This article has explained three return types of asynchronous functions. I hope you understood the
concept. Comments are always welcome. In the next few articles, we will dig more into the same topic.
Have a nice day.

Tasks in C# Asynchronous
Programming
Introduction

Welcome to the Asynchronous Programming in C# 5.0 article series. The previous two articles explained
what asynchronous programming is and how to implement it in C# 5.0. We also have seen various return
types of asynchronous functions. To read all those, please visit the following links.

 Asynchronous programming in C# 5.0: Part-1: Understand async and


await

 Asynchronous Programming in C# 5.0 Part 2: Return Type of


Asynchronous Method

This article explains Tasks in asynchronous programming. If we follow the previous two articles, (or if you
are already familiar with Tasks), then you will find that we are returning a Task from an asynchronous
function. But the question is, what is a Task? Let me give a single-line answer: "A Task is a basic unit
of the Task Parallel Library (TPL)". I know that a single-line answer is not enough for understanding what
a Task is, but don't worry; we will dig into it more since this article is dedicated to Tasks. (Not office tasks,
tasks of asynchronous programming!!) Ok, now let's be serious and proceed to the topic.

On a basic level, a task is nothing but a unit of work. Let's try to map them with real-life tasks to
understand them better.

 A task can run/start: Real-life tasks can run/start (read proceed).

 A task can wait: Real-life tasks wait too (my friend waited for seven days to get feedback on his
first proposal, though it was negative.)

 A task can cancel: No need to provide an example, you often cancel your task.

 A task can have a child Task: Yes, there are subtasks in people's lives.

 So, those are the features (better to say properties) of Tasks in asynchronous programming. A
Task can only run from its start to its finish, you cannot run the same task object two times. Now,
the question is, what is the solution for running the same task more than once? The answer is
you will need to create another Task object to run the same task.

Ok, let's try one small example to understand Tasks.

Have a look at the following code. Here we will create an object of the Task class.

1. using System;
2. using [Link];
3. using [Link];
4. using [Link];
5. using [Link];
6.

7. namespace Asynchronious {
8. class Program
9. {
10. public static void Main(String [] args)
11. {
12. Task t = new Task(
13. () => {
14. [Link](5000);
15. [Link]("Huge Task Finish");
16. }
17. );
18.

19. //Start the Task


20. [Link]();
21. //Wait for finish the Task
22. [Link]();
23. [Link]();
24. }
25. }
26. }

We are calling the Start() method to start the Task. After that, we are calling the Wait() method that
implies we are waiting for the task to finish. Here is the sample output.

How to Wait for a Task?

Let's try to understand how to delay (or sleep) a Task for a while. Have a look at the following example:

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6.

7. namespace Asynchronious
8. {

9. class Program
10. {

11. public static void Main(String [] args)


12. {
13. Task t = new Task(
14. () => {

15. [Link](5000);
16. [Link]("Huge Task Finish");

17. }
18. );

19.
20. //Start the Task

21. [Link]();
22.

23. //Wait for 1 second


24. bool rValue = [Link](1000);

25. [Link]("Main Process Finished");


26. [Link]();

27. }
28. }

29. }

In this example, we are waiting to finish a huge task for one second even after it has actually finished. So,
we learn how to continue to wait for a Task. Here is the output screen.

Implement Child Task

Here we will implement a child Task of another Task. Have a look at the following code:
1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. namespace Asynchronious

7. {
8. class Program

9. {
10. public static void Main(String [] args)

11. {
12. Task Parent = new Task(

13. () => {
14. Task Child = new Task(

15. ()=> {
16. [Link](2000);

17. [Link]("Inner Task Finish");


18. },

19. [Link]
20. );

21.
22. //Start Child Task

23. [Link]();
24. [Link](2000);

25. [Link]("Outer Task Finish");


26. }

27. );
28.

29. //Start the Task


30. [Link]();

31. [Link]();
32. [Link]();

33. }
34. }

35. }

At first we created a Parent Task that contains another child Task within it.
The innermost and outermost Tasks will sleep for two seconds. We are
running a child Task within the object of a parent Task.

Now, let's analyze the output. We see that at first, the outer Task is finishing,
and then the innermost Task finishes. Why is that? It is happening due to an
asynchronous call. The outer Task is running the innermost Task, but not
waiting for it. This is the beauty of an asynchronous call.

Get Status of Task

We can detect the status of any Task. Let's see in the following example:

1. using System;
2. using [Link];
3. using [Link];
4. using [Link];

5. using [Link];
6. using [Link];

7. namespace Asynchronious
8. {

9. class Program
10. {

11. public static void Main(String [] args)


12. {

13. Task t = new Task(


14. () => {

15. [Link](5000);
16. });

17.
18. [Link]();

19. [Link]();
20. [Link]([Link]);

21. [Link]("End of Main");


22. [Link]();

23. }
24. }

25. }

Here, we are starting the Task and then we are waiting for the Task to be
complete. In the next line, we are checking the status of the Task using the
Status property of the (Task) object. Now a question may arise: What is the
purpose of checking the status? There are many things to do, so we can run
another Task depending on the status of another Task. Let's see the output:
The status is showing RunToCompletion. It means that the Task is running
currently and it will complete.

Few more properties of Task class

Let's check a few more properties of the Task class. Have a look at the
following example:

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. using [Link];

7. namespace Asynchronious
8. {

9. class Program
10. {

11. public static void Main(String [] args){


12.
13. Task t = new Task(
14. () => {

15. [Link](5000);
16.

17. });
18.

19. [Link]();
20. [Link]("Cancelled:- " + [Link]);

21. [Link]("Completed:- " + [Link])


;
22. [Link]("Folted:- " + [Link]);

23. [Link]("End of Main");


24. [Link]();

25. }
26. }

27. }

Here we will check a few statuses of the Task object. For example, we are
interested in checking for the Cancel, Completed and Failed statuses of the
Task. In the example all are False. That means:

 Cancelled: The Task is not Cancelled

 Completed: It is not completed (still running)

 Faulted: There is no error or exception to run this Task.


Conclusion

In this article, we have learned what a Task is and the various properties of
tasks. In future articles, we will concentrate on exception handling in
asynchronous programming. Keep on reading this series. Hey!! Are you still
reading? Then that means both of us love asynchronous programming! Have
a nice day.

Next article >> Exception Handling in C# Asynchronous Programming

Exception Handling in C# Asynchronous


Programming

Introduction

Welcome to the Asynchronous Programming series. In the previous three


articles, we explained the async and await keywords and the return type of
asynchronous methods and tasks. You can read them here.

1. Asynchronous programming in C# 5.0: Part-1: Understand async and


await

2. Asynchronous Programming in C# 5.0 Part 2: Return Type of


Asynchronous Method

3. Asynchronous Programming in C# 5.0 Part 3: Understand Task in


Asynchronous programming.
In this article, we will explain Exception Handling in asynchronous
programming. I hope you are experienced with Exception Handling in C#,
but you may not know how to implement Exception Handling in
asynchronous programming. Let's see how to implement try-catch blocks in
asynchronous programming. Have a look at the following code.

Traditional Try-Catch in Asynchronous programming

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. using [Link];

7. namespace Asynchronious
8. {

9. class Test
10. {

11. public Task ShowAsync()


12. {

13. return [Link](()=>{


14. [Link](2000);

15. throw new Exception("My Own Exception");


16. });

17. }
18. public async void Call()

19. {
20. await ShowAsync();

21. }
22. }

23. class Program


24. {
25. public static void Main(String [] args)
26. {

27. Test t = new Test();


28. try

29. {
30. [Link]();

31. }
32. catch (Exception ex)

33. {
34. [Link]([Link]);

35. }
36. [Link]();

37. }
38. }

39. }

We have declared a Test class with an asynchronous function, ShowAsync(),


that will throw an exception. One more function (Call) will call the
ShowAsync() function. From the Main() function we are calling the Call()
function wrapping try catch blocks. We hope that in the catch block, the
exception will be handled. Have a look at the following output:

Oh! The catch is not handling an exception? Why? The reason is that it's
asynchronous in nature. As we know, in asynchronous programming, control
does not wait for the function's result and it executes the next line. So when
the function throws an exception, at that moment the program control is out
of the try-catch block. This is why it exists.

Implement try-catch within the function

Let's implement a try-catch block within an asynchronous function. This is


the solution to catch exceptions in asynchronous methods. Have a look at
the following code. If you look closely inside the ShowAsync() function, then
you will find we have implemented a try-catch within [Link](). Within
[Link](), all processes are executed synchronously (in our example). So, if
there is an exception, then it will be caught by the Exception Handling block.

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. using [Link];

7. namespace Asynchronious
8. {

9. class Test
10. {

11. public Task ShowAsync()


12. {

13. return [Link](() =>


14. {

15. try
16. {

17. [Link](2000);
18. throw new Exception("My Own Exception");

19. }
20. catch (Exception ex)

21. {
22. [Link]([Link]);

23. return null;


24. }

25. });
26. }

27. public async void Call()


28. {

29. try
30. {

31. await ShowAsync();


32. }

33. catch (Exception ex)


34. {

35. [Link]([Link]);
36. }

37. }
38. }

39. class Program


40. {

41. public static void Main(String [] args)


42. {

43. Test t = new Test();


44. [Link]();

45. [Link]();
46. }

47. }
48. }

Now, you may wonder: We have implemented a try-catch block within Task
and it's fine, but what need is there for implementing a try-catch within the
Call() function? The reason is because when an asynchronous function fails
to execute a Task, it throws a Task Cancelled exception. We need to
implement a mechanism to catch this exception.

Here is the output screen:

We see that now the Exception Handling block is capable of catching the
exception.

Now the question is: is it possible to wrap a try-catch block over an


asynchronous function as is done for traditional synchronous functions? The
answer is that we can, but with a limitation. What is the limitation? The
exception should occur outside of the Task process statement. Then the
Exception Handling block can catch the exception. Let's see the following
example:

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. using [Link];

7. namespace Asynchronious
8. {

9. class Test
10. {

11. public Task ShowAsync()


12. {

13. throw new Exception("My Own Exception");


14. return [Link](() =>

15. {
16. [Link](2000);

17. });
18. }

19. public async void Call()


20. {

21. try
22. {

23. await ShowAsync();


24. }

25. catch (Exception ex)


26. {

27. [Link]([Link]);
28. }

29. }
30. }

31. class Program


32. {

33. public static void Main(String [] args)


34. {

35. Test t = new Test();


36. [Link]();

37. [Link]();
38. }

39. }
40. }
Here the exception occurs outside of the Task, now the exception is caught
by the try catch block from the calling location. Here is the sample output:

Conclusion

This article has explained Exception Handling in asynchronous programming.


I hope you have understood it. In the next article, I would like to discuss a
few more real-world examples of asynchronous programming.

Next Article >> Asynchronous Programming in C# 5.0: Part Five: Access


Data Sing Asynchronous Function

Asynchronous Programming in C# 5.0 -


Access Data in Asynchronous Functions

Introduction
Welcome to the Asynchronous Programming in C# 5.0 article series. In
previous articles, we discussed many other topics in asynchronous
programming. You can read them here.

1. Asynchronous programming in C# 5.0: Part-1: Understand async and


await

2. Asynchronous Programming in C# 5.0 Part 2: Return Type of


Asynchronous Method

3. Asynchronous Programming in C# 5.0 Part 3: Understand Task in


Asynchronous programming.

4. Asynchronous Programming in C# 5.0 Part 4:Exception Handling in


Asynchronous Programming

In this article, we will try to implement a few real-time applications of


asynchronous programming. Here we will see in which scenario we can
implement asynchronous threads. Let's try to understand the situation.

To call a Web service

If we want to call a web service, then we can implement an asynchronous


function. This is because we know that in order to call a web service, it takes
time (for other reasons, like low internet speed, server down and so on).

If we want our application's performance to not decrease due to the low


response of the web service, then we can implement asynchronous
functions, or we can call this web service asynchronously.

To pull huge amounts of data from a database

Let's think of one situation wherein one form, (Windows or Web Form for
example), a huge amount of data needs to be pulled from the database.
Now, if we access the data synchronously, then the entire UI will block and
the user is unable to do anything until all database operations finish.

But if we do it asynchronously (or call the data fetching function


asynchronously) then the user is free to do her work while the data is loading
in the background.

Sometimes it's necessary to read a large file in an application. Reading the


file using the StreamReader object takes time. We can read this file
asynchronously, and then it will not affect the performance of the
application.

I hope those three examples are enough to understand the real-time


implementation of asynchronous functions. Now let's implement
asynchronous functions in a few scenarios.

Fetch data asynchronously

We will create one sample program to fetch data asynchronously. We have


created two functions to load data in the grid asynchronously. Let's create a
simple user interface containing two grids and one button. When we press a
button the grid will load asynchronously. Have a look at the following code:

1. using System;
2. using [Link];

3. using [Link];
4. using [Link];

5. using [Link];
6. namespace WindowsFormsApplication1

7. {
8. public partial class Form1 : Form

9. {
10. DataTable dt = new DataTable();

11. public Form1()


12. {

13. InitializeComponent();
14. [Link]("Id", typeof(int));

15. [Link]("Name", typeof(String));


16. [Link]("Surname", typeof(String));

17. [Link](1, "sourav", "kayal");


18. [Link](2, "Ram", "Kumar");

19. [Link](3, "Shyam", "Kymar");


20. }

21. private void Form1_Load(object sender, EventArgs


e)
22. {

23. }
24. public Task<DataTable> LoadData1()

25. {
26. return [Link](() => {

27. [Link](10000);
28. return dt;

29. });
30. }

31. public Task<DataTable> LoadData2()


32. {

33. return [Link](() =>


34. {

35. [Link](10000);
36. return dt;

37. });
38. }

39. private async void button1_Click(object sender, E


ventArgs e)
40. {

41. //Load Data Asynchronously


42. [Link] = await LoadData1()
;

43. [Link] = await LoadData2()


;
44. }

45. }
46. }

Here is the sample output:

We can see that one grid has loaded and the data still is not available in the
second grid. The most noticeable fact is that the user interface is not
collapsed in the data fetch operation. We can drag this window anywhere
and even resize it.
Now data has been populated in both grids.

So, this is an actual example of an asynchronous function. Here we have


loaded static data using a data table, but in practical usage, you may
implement data fetching operations from a database.

Conclusion

In this article, we learned how to access data asynchronously in C#. I hope


you have understood the concept. In future articles, we will see a few more
scenarios where we can implement the asynchronous mechanism.

 Access data

 Asynchronous function

 Asynchronous programming
 C# 5.0

 Fetch data asynchronously

Next Recommended ReadingAsynchronous Programming in C# 5.0 Part


6: 3 Best Practices in Asynchronous Programming

Asynchronous Programming in C# 5.0


Part 6: 3 Best Practices in Asynchronous
Programming

Welcome to the Asynchronous Programming in C# 5.0 article series. If you are an old reader
then you probably know what was explained in this series so far. If you are new then please
find the previous articles in the following links.

1. Asynchronous programming in C# 5.0: Part-1: Understand async and await

2. Asynchronous Programming in C# 5.0 Part 2: Return Type of Asynchronous Method

3. Asynchronous Programming in C# 5.0 Part 3: Understand Task in Asynchronous


programming.

4. Asynchronous Programming in C# 5.0 Part 4: Exception Handling in Asynchronous


Programming

5. Asynchronous Programming in C # 5.0 Parts 5: Access data using asynchronous


function.

As the title suggests, in this article we will explain a few best practices in Asynchronous
Programming. Let's try to understand them one by one with an example.
1. Avoid return Void from asynchronous function

We know that, there are three possible return types from an asynchronous function, they
are:

 Void

 Task

 Task<T>

It is recommended not to return void from any asynchronous function. Now the question is,
why? Let's explain. We will implement one asynchronous function with return type void.
Have a look at the following code. We have defined Asyncfun() with void return type.

Now, from the Call() function we are trying to call this asynchronous function. And we are
seeing that the compiler is saying that we cannot use the await keyword to call an
asynchronous function that returns void. So, we need to return either Task or Task<T>.
Then, again question is, why do asynchronous functions support void? Is there some use of
that? Yes, the use is there. Use void when you define an event handler with async qualifier,
as in the following.

Let's see, we have qualify Button1_Click() event as asynchronous and it's return type is void.

2. Implement exception handling block in proper place


Be careful when you implement a try-catch block in an asynchronous function. Don't treat an
asynchronous function as normal. Have a look at Following code.

using System;

using [Link];

using [Link];

using [Link];

namespace Asynchronious

class Program

public static async Task Asyncfun()

throw new Exception("This is my exception");

public static async void Call()

await Asyncfun();

public static void Main(String[] args)

try

Call();
}

catch (Exception ex)

[Link]([Link]);

[Link]();

When we run this code we get the following error.

So, the try-catch block fails to handle the exception. Now, the question is where to
implement the try-catch block? Implement the try-catch block within the asynchronous
function.

using System;

using [Link];

using [Link];

using [Link];
namespace Asynchronious

class Program

public static async Task<String> Asyncfun()

try

//Some business code is here

throw new Exception("This is my exception");

catch (Exception ex)

[Link]([Link]);

return null;

public static async void Call()

await Asyncfun();

public static void Main(String[] args)

Call();

[Link]();

}
}

In this code we wrapped the function of the asynchronous method with a try-catch
statement. Now we can handle exceptions thrown by the asynchronous function.

3. Don't implement asynchronous just because you can

Then why do we need to learn asynchronous programming? Hold on dear; let me explain
why. Asynchronous functions are for a time consuming process. The reason is when we call
an asynchronous function many operations happen behind the scenes. What are the
operations?

When we call a function asynchronously the operation between threads are changed,
executes context switching and copies the state of the current thread in variable and many
more, and to do al that it takes little (realy little?) time.

Let's implement two versions (one asynchronous and one synchronous) of the same function
and try to get the execution times.

using System;

using [Link];

using [Link];

using [Link];

using [Link];

using [Link];

using [Link];

using [Link];
namespace Asynchronious

class Program

public static async Task<String> Asyncfun()

//This is dummy return

return "Hello World";

public static async void CallAsync()

await Asyncfun();

public static string NonAsync()

//This is dummy return

return "Hello World";

public static void CallNonAsync()

NonAsync();

public static void Main(String[] args)

{
Stopwatch sw = new Stopwatch();

[Link]();

CallAsync();

[Link]("Asynchronous Call:- " + [Link]);

[Link]();

[Link]();

CallNonAsync();

[Link]("Synchronous Call:- " + [Link]);

[Link]();

[Link]();

Here is sample output.

Hmm, the asynchronous function does take much and much and much longer time than a
normal function. Hmm, if you don't believe this output, I will suggest you to run this code in
your system (you may even first call the synchronous function) and the result will not differ
much.

Ok, understood, then where do we need to implement the asynchronous function? This is
already explained in previous articles, please visit them.

Just keep in mind, the asynchronous scenario is suitable when we want to call another thread
(non .NET net) from our current .NET Thread.

Conclusion

This article has explain a few best practices for asynchronous programming. Hope you have
enjoyed them. Keep learning.

<< Previous article

 Asynchronous Function

 Asynchronous programming

 Asynchronous Programming Best Practice

 C# 5.0

Next Recommended ReadingAsynchronous Programming With C#

Asynchronous Programming With C#

C# supports both synchronous and asynchronous methods. Let's learn the


difference between synchronous and asynchronous and how to code in C#.
Interestingly enough, any method we normally create in C# is synchronous
by default. For example, the following method fetches data from a database
and binds it to a TextBox synchronously.

1. private void LoadData() {


2. // Create connection

3. SqlConnection conn = new SqlConnection(@ "network addre


ss= .; integrated
4. security = true; database = EmployeeDb ");

5. // Create command
6. string sql = @ "select EmpId,Name

7. from [Link] where EmpID <= 500 ";


8. // Data binding code goes here

9. try {
10. // Open connection

11. [Link]();
12. // Execute query via ExecuteReader

13. SqlDataReader rdr = [Link]();


14. while ([Link]()) {

15. [Link]("\nEmpID: ");


16. [Link]([Link](1) + "\t\t" + r
[Link](0));

17. [Link]("\n");
18. }

19. } catch (SqlException ex) {


20. [Link]([Link] + [Link], "Exce
ption Details");

21. } finally {
22. [Link]();

23. }
24. }

What is Synchronous
 Synchronous represents a set of activities that starts happening
together at the same time.

 A synchronous call waits for the method to complete before continuing


with program flow.

How bad is it?

 It badly impacts the UI that has just one thread to run its entire user
interface code.

 Synchronous behavior leaves end users with a bad user experience


and a blocked UI whenever the user attempts to perform some lengthy
(time-consuming) operation.

Business Scenario and Problem Statement

Consider a real-world business case in which a UI binds data to the data grid
by fetching it from the database. While data is being fetched and bound to
the grid the rest of the UI is blocked. Any attempt of interaction with other UI
controls will not be evident until the data loading is over. This UI blockage
gets over when data fetch-and-binding is completely done. Refer to "Figure
1-1 Synchronous Behavior" below
Figure 1-1 Synchronous Behavior

Solution to the Synchronous Problem

A synchronous method call can create a delay in program execution that


causes a bad user experience. Hence, an asynchronous approach (threads)
will be better. An asynchronous method call (cretion of a thread) will return
immediately so that the program can perform other operations while the
called method completes its work in certain situations.

The asynchronous method's behavior is different than synchronous ones


because an asynchronous method is a separate thread. You create the
thread; the thread starts executing, but control is immediately returned back
to the thread that called them time; while the other thread continues to
execute.

In general, asynchronous programming makes sense in two cases as,

 If you are creating a UI intensive application in which the user


experience is the prime concern. In this case, an asynchronous call
allows the user interface to remain responsive. Unlike as shown in
Figure 1-1.

 If you have other complex or expensive computational work to do, you


can continue; interacting with the application UI while wait for the
response back from the long-running task.

Asynchronous Patterns

There are various ways to use threads in applications. These recipes are
known as Patterns.

Asynchronous Programming Model Pattern

 Relies on two corresponding methods to represent an asynchronous


operation: BeginMethodName and EndMethodName

 Most often you must have seen this while using delegates or method
invocation from a Web Service.
Figure 1-2 APM Pattern

Event Based Asynchronous Pattern

 The Event-based Asynchronous Pattern has a single


MethodNameAsync method and a corresponding
MethodNameCompleted event

 Basically, this pattern enforces a pair of methods and an event to


collaborate and help the application execute a thread asynchronously

Figure 1-3 Event Based Pattern

Task based Asynchronous Pattern

 The Microsoft .NET Framework 4.0 introduces a new Task Parallel


Library (TPL) for parallel computing and asynchronous programming.
The namespace is "[Link]".

 A Task can represent an asynchronous operation and a Task provides


an abstraction over creating and pooling threads.
Figure 1-4 Task Based Pattern

C# 5.0 async and await based Asynchronous


Pattern
 Two new keywords, async and await, were introduced in C# 5.0
and .NET 4.5. These are implemented at the compiler level and built on
top of the "[Link]" feature of .NET 4.0.

 To work with async and await, you must have Visual Studio 2012

1. async void LoadEmployee_Click(object sender, RoutedEven


tArgs e) {
2. // ...

3. await [Link]();
4. // ...

5. }

Problem with older Asynchrnous Patterns

With earlier patterns, the programmer needed to do all the plumbing and
collaboration between a pair of methods (BeginMethod and EndMethod) or a
method and an event (MethodAsync and MethodCompleted) to make them
functional; see Figure 1-2 APM Pattern. This approach was a tedious job not
only in terms of syntax but also from sequence of statements inside the
method body.

C# 5.0 async/await offers a completely different and easy way to do


asynchronous programming. With this feature it's no longer the responsibility
of the programmer to do the syntax related tedious work, rather this is now
done by the keywords (C# 5.0 async / await) provided by the programming
language.

As a result, asynchronous code is easy to implement and retain its logical


structure. Hence now it is as easy as writing your normal method without
concern of any extra plumbing and so on. As shown in other asynchronous
patterns in which you need to deal with a pair of methods or a combination
of methods and events and so on.

Business Scenario

Consider a real-world business case, a WPF UI binding data to the data grid
by fetching a large number of rows from a database. While data is being
fetched and bound to a grid, the rest of the UI should continue to be
responsive. Any attempt at interaction with other UI controls must not be
blocked and data loading and binding must continue in parallel.. Refer to
"Figure 1-1 Synchronous Behavior" below.
Figure 1-5 Asynchronous Behavior

Let's Code

If you look at the code below, it looks like normal code as shown at the very
beginning of this article. The differences worth noting are highlighted in
yellow in the code block below.

1. Private async void LoadCustomersAsync() {


2. using(EmployeeDbEntities ent = new EmployeeDbEntities()
) {

3. IdbConnection conn = ([Link] as EntityConnectio


n).StoreConnection;
4. [Link]();

5. using(DbCommand cmd = (DbCommand) [Link]())


{
6. var query = from p in [Link]
7. where [Link]("FN") && [Link]("SN")
&& ([Link] + [Link]).Length > 3
8. select p;

9. //Convert linq query to SQL statement for CommandText


10. string str = ((ObjectQuery) query).ToTraceString(
);

11. [Link] = str;


12. // Invoke Async flavor of ExecuteReader

13. var task = await [Link]();


14. //translate retieved data to entity customer

15. var cust1 = await [Link](


16. () => [Link] < EmployeeDetails > (task).To
List < EmployeeDetails > ());

17. [Link] = cust1;


18. }

19. }
20. }

As you noticed, the flow looks very natural and no extra plumbing appears in
the code. Except async/await, task and of course the asynchronous flavor of
the main function that is retrieving data from the database; in our case,
ExecuteReaderAsync() is the method.

This code will allow you to perform UI interaction; when data is being fetched
and grid binding is taking place, refer to the Figure 1-6 async/await in action.
Figure 1-6 async/await in action (as you can see in image 36K + rows pulled)

Legacy Operations

Microsoft suggests that with the release of .NET 4.5, the following commonly
used methods should be considered as legacy operations. When possible and
if you are usng .NET 4.5 then you must use async and await to do
asynchronous programming in your application.
Figure 1-7 Legacy Operations

What if you don't have Visual Studio 2012

Since Visual Studio 2012 is still not adopted by many development teams in
various organizations and many developers still use Visual Studio 2010. So,
can they use async and await syntax there?

Microsoft released an async CTP that is supposed to work well with Visual
Studio 2010 (without SP1) and allow the developers to use the same syntax.

Search for "async CTP" in Bing or Google.

Figure 1-8 Async CTP download page

Side-by-Side Comparison of various ways techniques


Figure 1-9 Side-by-Side comparison on various techniques

 asynchronous methods

 Asynchronous Programming

 C# 5.0

 C# 5.0 async

 synchronous methods

Next Recommended ReadingAsynchronous Programming In C#


Asynchronous Programming In C#
Introduction
You might have already heard about asynchronous programming in the .NET framework before. In this
article, I will explain the structure of async and await keyword, how we benefit from this programming
model, and will illustrate through an example.

Below are the benefits of this model:

1. Improve the responsiveness and performance of an application by not waiting for long-running
operations/functions. Instead, the application can continue with other work which does not
depend on long-running tasks. For example, .NET types=
JsonSerializer,StreamReader,StreamWriter,XmlReader ,XmlWriter and HttpClient have async
methods in areas of Web Access and Files.

2. Organize your code in a better way than the traditional way of thread creation and handling. With
async and await, there is less code and it is more maintainable. For example, better than
BackgroundWorker class for I/O bound operations because code is easily maintainable and does
not have to guard against race conditions.

So ideally, a software developer should focus on business logic and how asynchronous works is taken
care of by the async and await keyword structure.

The following changes are required to change a normal function into an asynchronous function using
async/ await.

1. The Async keyword should be added in the function definition, thereby enabling to use await
inside the function body.
2. The await keyword is a must inside the function body otherwise method runs in a synchronous
way.
3. The asynchronous function name should end with Async, this helps us to identify the async
method.
4. The return type of asynchronous function should be void or Task or Task<T> where T is the
return data type or any other type that has a GetAwaiter method(C# 7.0).

For example Public Task<Student> ReturnStudentDetailsAsync(), here, Student is the name of the class.
The void return type is primarily used to define event handlers where the void return type is required.

Async methods can't declare in, ref, or out parameters, but the method can call methods that have such
parameters. In the same way, it can't return value by reference but it can call the method with ref return
values.
For illustration, I created a C# console application of downloading the content of a list of websites as a
string.

static async Task Main(string[] args)


{
List<string> list = new List<string>();
[Link](@"[Link]
asynchronous-programming-model");
[Link](@"[Link]
[Link](@"[Link]
[Link](@"[Link]
Task<List<WebsiteDataModel>> datamodelTask = RunDownloadAsync(list);
DoIndependentWork();
var output = await datamodelTask;
foreach(var a in output)
{
PrintResults(a);
}
[Link]();
}
Here we have an async main function whose return type is Task.

You can also see we haven't used await when RunDownloadAsync is called. Instead, we have used it in
line number 15. So let's discuss the flow of execution.

 A list of strings is declared, and 4 websites are added as input arguments to list and pass as an
argument to RunDownloadAsync (asynchronous function.)

 RunDownloadAsync will wait to download the content from the website or some other
interruptions occurs. To avoid blocking resources, RunDownloadAsync will yield control to its
calling function Main.

RunDownloadAsync returns a Task<List<WebsiteDataModel>> where WebsiteDataModel is a class


representing downloaded website content and it's URL and Main assign the result to datamodelTask
variable.

 Control returns back to the calling the function. It and Main can continue work with other lines of
code not dependent on RunDownloadAsync output. This is represented by a call to synchronous
method DoIndependentWork.

 DoIndepedentWork does its work and returns control to the caller.

 The main method has run out of work and it can't proceed ahead without getting a result from the
RunDownloadAsync function. Therefore, it uses the await keyword in line number 15 to suspend
its progress and will only proceed ahead when function execution is completed.

 RunDownloadAsync completes and produces a list of WebsiteDataModel class results. Here the
await operator retrieves the result from datamodelTask. The assignment statement assigns the
retrieved result to output.
 The foreach loop iterates through the output received and print the results in a console window.

Other lines of source code:

private static void DoIndependentWork()


{
[Link]("Independent Work");
}
private static async Task<List<WebsiteDataModel>> RunDownloadAsync(List<string> data)
{
var list = new List<WebsiteDataModel>();

foreach(string site in data)


{
var results=await [Link](()=>DownloadWebsite(site));
[Link](results);
}
return list;
}
private static WebsiteDataModel DownloadWebsite(string websiteURL)
{
var output = new WebsiteDataModel();
var client = new WebClient();

[Link] = websiteURL;
[Link] = [Link](websiteURL);

return output;
}
private static void PrintResults(WebsiteDataModel data)
{
[Link]($"{ [Link] } downloaded: { [Link] } characters long.
{ [Link] }");
}

Here, in RunDownloadAsync, we first created a return variable then loop through a list of websites and
use the await keyword to suspend the function execution until DownloadWebsite function execution is not
completed. In a way, the program is running in a synchronous way, as we are not proceeding ahead until
website contents are downloaded and might not see much performance improvements as compared to
the synchronous method.

We can improve upon this scenario by rewriting RunDownloadAsync by downloading website contents in
a parallel way.

private static async Task<List<WebsiteDataModel>> RunDownloadAsync(List<string> data)


{
var list = new List<WebsiteDataModel>();
List<Task<WebsiteDataModel>> tasks = new List<Task<WebsiteDataModel>>();
foreach (string site in data)
{
[Link]([Link](() => DownloadWebsite(site)));
}
var results = await [Link](tasks);
list = [Link]();
return list;
}
Here, a List of Task of type WebsiteDataModel is created, then added as a task for each of the website
contents to be downloaded in tasks variable and which runs in a parallel way.

Now function execution is suspended in line number 12 until all the task executions are finished, this is
done by using the await keyword. The output of line no 12 is assigned to the return list variable by
converting it to a list.

Reference

The Task Asynchronous Programming (TAP) model with async and await (C#)" | Microsoft Docs

 Asynchronous Programming

 Asynchronous Programming In C#

 C#

Common questions

Powered by AI

GetResponseAsync is an asynchronous method that stops its execution at the await keyword, allowing the application to continue processing other messages, hence maintaining responsiveness. Unlike the synchronous GetResponse, which can block the application and make it unresponsive during execution, the asynchronous method resumes once the I/O operation is completed, allowing for seamless execution flow .

The Task's Status property is used to monitor and determine the current state of a running task. It provides information about whether the task has completed, is running, faulted, or was canceled. This helps in efficiently managing workflow by allowing decision-making processes based on task completion, such as conditionally running subsequent tasks or handling errors, increasing robustness and improving overall application efficiency .

The Task Parallel Library (TPL) allows async and await keywords to be used for CPU-intensive operations by running these tasks on separate threads, while still providing the benefits of non-blocking UI threads. Although it's not truly asynchronous since it consumes a thread, it helps in offloading heavy computations from the UI thread, resulting in a more responsive application. This integration is crucial for enhancing performance with hardware concurrency .

Improperly handling async/await can lead to deadlocks, particularly when asynchronous code is awaited synchronously using Task.Wait or Result. This causes the current thread to block, preventing the continuation from executing when it posts a completion message to the queue. The main thread remains blocked waiting for the completion that itself cannot proceed until it gets processed, thereby creating a deadlock situation .

Including a try-catch block inside asynchronous calls is crucial because errors occurring within asynchronous methods might not be caught by surrounding synchronous try-catch blocks due to non-blocking execution. Implementing try-catch within the Task.Run block ensures exceptions are caught immediately as they occur, unlike traditional synchronous methods where exceptions are caught outside, reflecting where and when they actually occur during program execution .

Task.Delay within an asynchronous function suspends the execution of that task without blocking the thread. This allows the system to perform other tasks during the delay period, conserving resources, and maintaining application responsiveness. In contrast, Thread.Sleep blocks the executing thread, preventing other operations from utilizing the blocked thread, potentially leading to decreased performance and a less responsive application .

Using async void as a return type can lead to unintended issues, as it allows methods to return without the caller awaiting their completion. This means you cannot synchronize their completion, leading to potential unhandled exceptions or unintended behavior. It's generally advised to restrict async void to event handlers only, as they inherently do not return values .

In traditional synchronous methods, exceptions are handled directly where they occur using try-catch blocks, providing immediate feedback on errors. In asynchronous methods, exceptions must be handled within the asynchronous task or awaited operation due to the non-blocking nature of execution. This may require embedding try-catch blocks in places where the task runs to ensure exceptions are caught as they arise, unlike synchronous methods where surrounding try-catch blocks suffice. This necessitates a deeper integration of error handling into asynchronous logic to account for task continuation and potential uncaught exceptions during asynchronous execution .

Asynchronous I/O operations contribute to the throughput of server applications by freeing up threads while waiting for I/O operations to complete. This allows other work to be performed on those threads in the interim, optimizing resource usage and allowing the server to handle more requests concurrently. While individual operations may show slightly increased latency, the overall processing capacity and responsiveness of the server are improved, resulting in better throughput .

Excessive use of threads in a multi-threading environment can lead to resource contention as each thread occupies system memory and CPU resources, potentially slowing down application performance. Asynchronous programming mitigates this by releasing threads back to the pool during I/O-bound operations, thereby optimizing resource usage and increasing application responsiveness and throughput without unnecessary thread occupation .

You might also like