Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Real advantages of Async-Await?

Earlier i've posted this question related to applying Async-Await at client or at service. Do read the question before going ahead with this question as it is tightly coupled with the question.

Based on the answer i've tested the code for C# 4.0 (TPL) and C# 5.0 (Async - Await). I am calling the service using async and sync version of the method provided by the service and comparing the number of threads used in each case. Following is the code i'm using to test the resources used:

MAIN METHOD

List<Task<string>> tasksList = new List<Task<string>>();
List<int> asyncThreads = new List<int>();
List<int> tplThreads = new List<int>();
Stopwatch watch = new Stopwatch();
watch.Start();

// Call the Async version of the method
for (int i = 0; i < 500; i++)
{
    tasksList.Add(GetNameFromServiceAsync("Input" + i.ToString(), asyncThreads));
}

Task.WaitAll(tasksList.ToArray());

watch.Stop();

foreach (var item in asyncThreads.Distinct())
{
    Console.WriteLine(item);
}

Console.WriteLine("(C# 5.0)Asynchrony Total Threads = " + asyncThreads.Distinct().Count());
Console.WriteLine(watch.ElapsedMilliseconds.ToString());

watch.Restart();

tasksList.Clear();

// Call the normal method
for (int i = 0; i < 500; i++)
{
    tasksList.Add(GetNameFromService("Input" + i.ToString(), tplThreads));
}

Task.WaitAll(tasksList.ToArray());

watch.Stop();

foreach (var item in tplThreads.Distinct())
{
    Console.WriteLine(item);
}

Console.WriteLine("(C# 4.0)TPL Total Threads" + tplThreads.Distinct().Count());

Console.WriteLine(watch.ElapsedMilliseconds.ToString());

Async and Sync CAlls To the service

static async Task<string> GetNameFromServiceAsync(string name, List<int> threads)
{
  Console.WriteLine(" Start Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
    var task = await client.GetNameAsync(name);
    threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
   // Console.WriteLine("End GetNameFromServiceAsync Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
    return task;
}

static Task<string> GetNameFromService(string name, List<int> threads)
{

    var task = Task<string>.Factory.StartNew(() =>
        {
            threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
         //   Console.WriteLine("GetNameFromService Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
            return client.GetName(name);
        });

    return task;
}

Now I've worked on the answer and find out following results:

  • If i make 500 calls to the service it uses only 4-5 threads.
  • The TPL calls makes around 44-45 threads.
  • Time for Async calls is around 17 - 18 seconds
  • Time for TPL calls is around 42 - 45 seconds.

I want to have some feedback on my findings so that it can be useful to the other community members as well. Is it what the answer of my earlier question??

EDIT

Q. My observation concludes that if we use Async-Await instead of TPL's Task.Factory.startNew , then it will consume lesser threads. HOW CORRECT IS THIS? IF NO, THEN WHAT IS THE RIGHT DIRECTION TO COME UP WITH SUCH COMPARISON?

Q. As i am learning async - await, i want to prove its worth by some sort of comparison and solid code.

like image 298
Learner Avatar asked Oct 01 '12 12:10

Learner


1 Answers

Client-side async (compared to synchronous code) generally improves responsiveness at a slight cost of memory.

Server-side async (compared to synchronous code) generally improves scalability by reducing memory/thread usage. These advantages also apply to client-side async (compared to multithreaded code).

Both of these are extreme generalizations and there are certainly situations where they're wrong.

Update:

My observation concludes that if we use Async-Await ..., then it will consume lesser threads.

async / await enable maintainable asynchronous code. By themselves, they don't have anything to do with creating threads. However, they are often used with Task.Run (or Task.Factory.StartNew) to create background tasks.

As i am learning async - await, i want to prove its worth by some sort of comparison and solid code.

async and await are compiler transformations. They make it easier to write asynchronous programs - that is all.

If you compare them to synchronous code, then you'll usually see improved responsiveness and/or scalability. If you compare them to existing asynchronous code, then they'll usually be slightly less efficient but more than make up for that in terms of code maintainability.

like image 101
Stephen Cleary Avatar answered Oct 23 '22 05:10

Stephen Cleary