Async expects performance in web applications

So far, I think I figured out the concepts of how waiting async can make your application more responsive, but I hung up on two points:

Layer States Is the expectation of async expected to go from the repository level all the way down to the MVC or WCF layer in order to gain performance benefits, or can I just perform asynchronous operations on my repository methods that are taking a long time?

"waiting" for use . If I can just work at the repository level then one part I don't understand. Using this (low-level) approach, would a thread be able to service incoming client requests while waiting for the associated io code to complete?

I put together a sample console application, in my opinion, while a lengthy work is in progress, another user can make a request to my web application. Using my little library (to make it easier to integrate and handle exceptions), will their request be served by a deferred thread, or will it not voidTask.Wait();

block the thread?

public class AsyncTest
{
    public void RunTest()
    {
        try
        {
            using (var task = new RunTask(LongRunningTask))
            {
                Console.WriteLine("Echo two things:");

                for (int i = 0; i < 2; i++)
                {
                    var input = Console.ReadLine();
                    Console.WriteLine(string.Format("Echoing \"{0}\"", input));
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error, hm, what happened??");
            Console.WriteLine();
            Console.WriteLine(e.Message);
            Console.WriteLine(e.StackTrace);
        }
    }

    public void LongRunningTask()
    {
        var totals = 0;

        for (int i = 0; i < 30; i++)
        {
            Thread.Sleep(1000);
            totals += 5;

            if (i == 25)
                throw new ArgumentException("I can't handle this! Errorr!!@!@");

            Console.WriteLine(string.Format("LongRunningTask Step {0}...", (i + 1)));
        }
    }
}

public class RunTask : IDisposable
{
    public delegate void IOBoundOperations();
    private Task voidTask;

    public RunTask(IOBoundOperations task)
    {
        voidTask = Execute(task);
    }

    async public Task Execute(IOBoundOperations task)
    {
        await Task.Run(() =>
        {
            task();
        });
    }

    public void Dispose()
    {
        try
        {
            voidTask.Wait();
        }
        catch
        {
            throw new AsyncException("Failed to run task asynchronously: " + 
                voidTask.Exception.InnerException.Message, voidTask.Exception.InnerException);
        }
    }
}

      

I put a wait because I will need this for tasks that will return data to the calling code that it can depend on. I also did this because I noticed that the process would not terminate until the thread finished my asynchronous stuff.

I can find a lot of information about async / await and it will be useful, just nothing in this particular aspect.

+3


source to share


4 answers


To get any benefit from the async

/ paradigm await

, you will need to push it to the top, be your MVC / Web API action (by marking the action as async

and returning a Task

) or in your Web Forms methods (by standard naming them like async void

setting the attribute async

to page itself).

Plus, you only have two options:

  • A call Task.Wait()

    that blocks it, so you won't get asynchronous behavior.
  • Just let this float away without joining that thread in any way, which is probably not ideal (even for things like logging that don't return anything, the IIS thread pool system doesn't like floating threads, so avoid using that here ).

That said, you are saying that another user can make a call to your web server if you did, which is true, but it is important to note that ASP web applications are always "asynchronous" as they have many threads available to them Implementing async

/ await

is a good idea in principle and helps improve the efficiency of these dedicated threads and potentially picks up the number of concurrent connections available, but does not need to allow, say, two concurrent requests to run at once. The thread pool will handle this on its own.




If you're worried about going through your entire codebase and exchanging synchronous calls with their counterparts ...Async()

, remember that you don't have to do everything at once. It's okay if you can, simply because asynchronous calls have some of the benefits listed earlier, but remember that you can simply set a return method to return Task.FromResult(object)

to support the asynchronous contract.

Obviously this doesn't behave asynchronously, but it's good to keep in mind when you're porting existing code or writing a library, because time will be doing more and more things that implement this pattern and you can design it to welcome it now. rather than wanting you to do it later.

+1


source


As others have said, you don't really understand the real power of async IO in your example.

People are often "scared" when they realize that an asynchronous transition is "completely" from the store to the controller itself. As I always say, don't fight, let it grow naturally in your codebase when you start implementing it. I recommend not to do any shortcuts with synchronization over asynchronous and vice versa, put extra effort (if necessary) to export both APIs separately.



But as @usr said, you don't always need to do async IO, even that is possible. Sure everyone wants to ride the bandwagon async-await

because it's a cool thing, but before asking myself, I am going to beat a lot of parallel requests, where do I really benefit from asynchronous I / O? Don't forget that although minimal, there async-await

is some overhead.

In conclusion, a little personal story. I recently started working on an ASP.NET Web API project that was getting into a SQL database and doing some heavy computation. The challenge was to make the computation faster, and I wondered if accessing async databases would help (I had a feeling it wasn't, but I had to try). After adding the asynchronous API and bubbling it all over the methods (which was not a small effort in itself), the overall performance actually turned out to be humiliating (as I assumed). So make sure you are using async IO for the right reasons.

+2


source


You don't seem to have a clear understanding of why asynchronous I / O is useful. It unblocks threads that preserve the memory stack and avoid overloading the bandwidth of threads.

Wait

clearly blocks the thread because this function does not return until the target completes. Thread resources are consumed during the call.

You need to make an asynchronous chaining of whole calls. If you do only asynchronous ayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

Please note that most web applications cannot increase bandwidth or reduce latency using async IO. You should understand that asynchronous I / O is good for making good calls. Don't fall for the hype. See Should we switch to using asynchronous I / O by default? and Why does EF 6 tutorial use asynchronous calls? ...

0


source


Using async / await can be very handy with all I / O related activities. An example action is SaveAnalytics (), which takes 100ms. if done synchronously, the thread will block in 100ms. if done asynchronously, the stream will be released just before all SaveAnalytics () data is saved in / database / whatever. when this save is in progress, another thread is used to return the thread to the client.

So what are the benefits of this? streams of the road! if you need a scalable application, you can say that you can gain a lot from the cloud by making all your I / O calls asynchronous.

If your web application is under heavy load, you will not receive a "503" message, which means "server is busy", which also means that there is not a single thread in the streaming stream that should be served to the client (they may all be busy waiting synchronously ).

The user might not notice anything because they click the Save button and see a message saying that Analytics has been saved. Everything happens asynchronously under water.

So, to remind you, it's all about the scalability of your application. If your application is not heavily used, then you shouldn't make all your methods asynchronous.

0


source







All Articles