2

I have a doubt that is there any performance gain if I use Async feature in Data Access Layer as below :

public async Task<IEnumerable<TrnApplicant>> GetAllMemberApplicantsAsync(String webReferenceNumber)
{
    using (var context = new OnlineDataContext())
    {
        var applicant = await Task.Run(() => context.Applicants.First(
                app => app.RefNo.Equals(webReferenceNumber, StringComparison.OrdinalIgnoreCase)) );

        return GetApplicantsInGroup(applicant.ApplicantsGroupId);
    }      
}

Also if not when does it make more sense?

2
  • It will never be faster on a single request the advantage is that it doesn't block. Commented Oct 6, 2014 at 10:37
  • Depends on how to measure performance. For a single user using a your ASP.Net server, there will be a performance drop. For serving 1M hit/s you would find benefit (assuming you avoid Task.Run and only async the I/O). Commented Oct 6, 2014 at 10:37

2 Answers 2

12

Consider this.

You call someone and ask them to do something for you. While they do it, you wait on the line, waiting for them to say "It's done". This is synchronous work. The act of calling them "blocks" until they're done with the job, and then you can get back to whatever you were doing, afterwards.

The alternative, asynchronous way, would be for you to make the call, but instead of waiting on the phone you hang up, and do something else while they work. Once they call you back, saying "It's done", you go back to doing whatever you needed their results to do.

Now, if you have nothing to do while you wait, there will be absolutely no performance gain, instead quite the opposite. The overhead of having the other party call you back will instead add to the total amount of work to do.

So with the above description of asynchronous work, do you have anything your code could do while it waits for the data access layer to complete its job?

If not, then no, there would be no performance gain.

If yes, then there could be performance gains.


Now, having said all that, I read the comment below my answer, and then I re-read your code a bit more carefully, and I believe that you are not really taking advantage of proper asynchronous code here.

The best way would be for you to use some kind of system or code that does asynchronous I/O properly. Your code calls Task.Run, which is actually the same as just plunking a different person down in front of the phone, doing the waiting for you.

For instance, consider SqlCommand, which may be the actual code doing the talking to the database here, it has two interesting methods:

Now, if you call the first one, on a thread created with Task.Run, you are in effect still blocking, you're just asking someone else to do it for you.

The second, however, is as I described above.

So in your particular case I would try to avoid using Task.Run. Now, depending on the load of your server, there may be advantageous to do it like that, but if you can I would switch to using the asynchronous methods of the underlying objects to do it properly.

Sign up to request clarification or add additional context in comments.

3 Comments

In this particular case there is one more thing to consider. The async behaviour is done via Task.Run which is equivalent to grabbing the nearest warm body to wait in line for you. This is the WORST kind of async, because you lose a warm body (a thread), which could be doing some other useful work, and you add the complexity of all this phoning about.
Thanks for the reply. Actually I was thinking the same. I just needed someone else to confirm.
Also, there is only a benefit to proper async if the backend can scale further than the ASP.NET server.
0

Using the async feature in the data access layer can provide performance gains in certain scenarios. In the provided code, the async and await keywords are used to make the method asynchronous, allowing the calling code to await the result without blocking the thread.

In the given code, the use of await Task.Run() is not recommended because it is potentially blocking a thread unnecessarily. The Task.Run method should generally be used to offload CPU-bound work to a background thread, but in this case, it's being used to wrap an asynchronous operation (context.Applicants.First()).

To improve performance, you can modify the code as follows:

public async Task<TrnApplicant> GetMemberApplicantAsync(string webReferenceNumber)
{
    using (var context = new OnlineDataContext())
    {
        var applicant = await context.Applicants.FirstAsync(
            app => app.RefNo.Equals(webReferenceNumber, StringComparison.OrdinalIgnoreCase));

        return GetApplicantsInGroup(applicant.ApplicantsGroupId);
    }
}

In this modified code, the FirstAsync method is used instead of First to perform the database query asynchronously. This allows the calling thread to be released while waiting for the database operation to complete, which can improve the responsiveness and scalability of the application.

It makes more sense to use async/await when working with I/O-bound operations such as network requests, file system operations, and database queries. By using asynchronous operations, you can free up threads to handle other requests, leading to better resource utilization and improved application responsiveness.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.