Asynchronous controller and ASP.NET thread handling - asp.net-mvc

I have a web application with web layer is a ASP.NET MVC 3 web application, service layer is WCF, database is MSSQL
In this article: http://blogs.msdn.com/b/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx , it mentioned that I should do asynchronous processing "when the benefit of switching threads out weights the cost of the context switch.", "For example, if you make an asynchronous web service request to a remote server"
Does that mean, in every request, I should try as much as I can to use asynchronous processing (in ASP.NET MVC I assume it's asynchronous controller instead of PageAsyncTask as in ASP.NET, correct me if I'm wrong) whenever there's a call to WCF service (or if I don't use WCF service, then whenever I have a call to database) to increase the throughput of server, increase number of requests that server can process at one time?
Another question which is a bit related: does anyone know or can point me to an article that explains about connection limit when connecting to WCF from web layer like this? I heard that the limit is 5 concurrent connections at a time for WCF but cannot confirm. If it's 5 concurrent connections, it means the bottleneck is in WCF even if I increase throughput of web layer?
Thank you very much

Does that mean, in every request, I should try as much as I can to use asynchronous processing
There's a benefit for doing this only if you have I/O operations (remote HTTP call such as a WCF service call, database call, ...). But you should do that only after you perform extensive load tests and have determined that synchronous calls are a bottleneck for your application in case you have such high processing requirements. In most cases the complexity of the asynchronous code and the risks of making very hard to find bugs outweigh the benefits.
does anyone know or can point me to an article that explains about connection limit when connecting to WCF from web layer like this?
I am not aware of the existence of such limit.

Related

In asp.net-mvc, what is the correct way to do expensive operations without impacting other users?

I asked this question about 5 years ago around how to "offload" expensive operations where the users doesn't need to wait for (such as auditng, etc) so they get a response on the front end quicker.
I now have a related but different question. On my asp.net-mvc, I have build some reporting pages where you can generate excel reports (i am using EPPlus) and powerpoint reports (i am using aspose.slides). Here is an example controller action:
public ActionResult GenerateExcelReport(FilterParams args)
{
byte[] results = GenerateLargeExcelReportThatTake30Seconds(args);
return File(results, #"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "MyReport.xlsx");
}
The functionality working great but I am trying to figure out if these expensive operations (some reports can take up to 30 seconds to return) are impacting other users. In the previous question, I had an expensive operation that the user DIDN"T have to wait for but in this case he does have to wait for as its a syncronoous activity (click Generate Report and expectation is that users get a report when its finished)
In this case, I don't care that the main user has to wait 30 seconds but i just want to make sure I am not negatively impacting other users because of this expensive operation, generating files, etc
Is there any best practice here in asp.net-mvc for this use case ?
You can try combination of Hangfire and SignalR. Use Hangfire to kickoff a background job and relinquish the http request. And once report generation is complete, use SignalR to generate a push notification.
SignalR notification from server to client
Alternate option is to implement a polling mechanism on client side.
Send an ajax call to enque a hangfire job to generate the report.
And then start polling some api using another ajax call that provides status and as soon report is ready, retrieve it. I prefer to use SignalR rather than polling.
If the report processing is impacting the performance on the web server, offload that processing to another server. You can use messaging (ActiveMQ or RabbitMQ or some other framework of your choice) or rest api call to kick off report generation on another server and then again use messaging or rest api call to notify report generation completion back to the web server, finally SignalR to notify the client. This will let the web server be more responsive.
UPDATE
Regarding your question
Is there any best practice here in asp.net-mvc for this use case
You have to monitor your application overtime. Monitor both Client side as well as server side. There are few tools you can rely upon such as newrelic, app dynamics. I have used newrelic and it has features to track issues both at client browser as well as server side. The names of the product are "NewRelic Browser" and "NewRelic Server". I am sure there are other tools that will capture similar info.
Analyze the metrics overtime and if you see any anomalies then take appropriate actions. If you observe server side CPU and memory spikes, try capturing metrics on client side around same timeframe. On client side if you notice any timeout issues, connection errors that means your application users are unable to connect to your app while the server is doing some heavy lifting. Next try to Identify server side bottlenecks. If there is not enough room to performance tune the code, then go thru some server capacity planning exercise and figure out how to further scale your hardware or move the background jobs out of the web servers to reduce load. Just capturing metrics using these tools may not be enough, you may have to instrument (log capturing) your application to capture additional metrics to properly monitor application health.
Here you can find some information about capacity planning for .net application from Microsoft.
-Vinod.
These are all great ideas on how to move work out of the request/response cycle. But I think #leora simply wants to know whether a long-running request will adversely impact other users of an asp.net application.
The answer is no. asp.net is multi-threaded. Each request is handled by a separate worker thread.
In general it could be considered a good practice to run long running tasks in background and give some kind of notification to user when the job is done. As you probably know web request execution time is limited to 90 seconds, so if your long running task could exceed this, you have no choice but to run in some other thread/process. If you are using .net 4.5.2 you can use HostingEnvironment.QueueBackgroundWorkItem for running long running tasks in background and use SignalR to notify user when the task is finished the execution. In case that you are generating a file you can store it on server with some unique ID and send to user a link for downloading it. You can delete this file later (with some windows service for example).
As mentioned by others, there are some more advanced background task runners such as Hangfire, Quartz.Net and others but the general concept is the same - run task in backround and notify user when it is done. Here is some nice article about different oprions to run background tasks.
You need to use async and await of C#.
From your question I figured that you are just concerned with the fact that the request can be taking more resources than it should, instead of with scalability. If that's the case, make your controller actions async, as well as all the operations you call, as long as they involve calls that block threads. e.g. if your requests go through wires or I/O operations, they will be blocking the thread without async (technically, you will, since you will wait for the response before continuing). With async, those threads become available (while awaiting for the response), and so they can potentially serve other requests of other users.
I assumed you are not wandering how to scale the requests. If you are, let me know, and I can provide details on that as well (too much to write unless it's needed).
I believe a tool/library such as Hangfire is what your looking for. First, it'll allows for you to specify a task run on a background thread (in the same application/process). Using various techniques, such as SignalR allows for real-time front-end notification.
However, something I set up after using Hangfire for nearly a year was splitting our job processing (and implementation) to another server using this documentation. I use an internal ASP.NET MVC application to process jobs on a different server. The only performance bottleneck, then, is if both servers use the same data store (e.g. database). If your locking the database, the only way around it is to minimize the locking of said resource, regardless if the methodology you use.
I use interfaces to trigger jobs, stored in a common library:
public interface IMyJob
{
MyJobResult Execute( MyJobSettings settings );
}
And, the trigger, found in the front-end application:
//tell the job to run
var settings = new MyJobSettings();
_backgroundJobClient.Enqueue<IMyJob>( c => c.Execute( settings ) );
Then, on my background server, I write the implementation (and hook in it into the Autofac IOC container I'm using):
public class MyJob : IMyJob
{
protected override MyJobResult Running( MyJobSettings settings )
{
//do stuff here
}
}
I haven't messed too much with trying to get SignalR to work across the two servers, as I haven't run into that specific use case yet, but it's theoretically possible, I imagine.
You need to monitor your application users to know if other users are being affected e.g. by recording response times
If you find that this is affecting other users, you need to run the task in another process, potentially on another machine. You can use the library Hangfire to achieve this.
Using that answer, you can declare a Task with low priority
lowering priority of Task.Factory.StartNew thread
public ActionResult GenerateExcelReport(FilterParams args)
{
byte[] result = null;
Task.Factory.StartNew(() =>
{
result = GenerateLargeExcelReportThatTake30Seconds(args);
}, null, TaskCreationOptions.None, PriorityScheduler.BelowNormal)
.Wait();
return File(result, #"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "MyReport.xlsx");
}
Queue the jobs in a table, and have a background process poll that table to decide which Very Large Job needs to run next. Your web client would then need to poll the server to determine when the job is complete (potentially by checking a flag in the database, but there are other methods.) This guarantees that you won't have more than one (or however many you decide is appropriate) of these expensive processes running at a time.
Hangfire and SignalR can help you here, but a queueing mechanism is really necessary to avoid major disruption when, say, five users request this same process at the same time. The approaches mentioned that fire off new threads or background processes don't appear to provide any mechanism for minimizing processor / memory consumption to avoid disrupting other users due to consuming too many resources.

How to handle multiple data connections at once

I have an ASP.NET MVC application which gathers data from multiple Databases.
The databases hold information for various sites and for every new site we have a new Database. The database for each site is connected at two points, from the site and then from HQ.
A web application updated data every minute from the site and the data is is served to the HQ (via another web application) every minute. Sometimes the application response is very slow and from what I have investigated, it may be because the connection pool starts filling up swiftly.
I want to ask what is the best approach to such application, where I can get the best performance out of it. Any guidance is welcome.
How to improve your web application performance regarding to database, really depends on your architecture. But there are some general rules which you should always follow:
Check about thread starvation:On the Web server, the .NET Framework
maintains a pool of threads that are used to service ASP.NET
requests. When a request arrives, a thread from the pool is
dispatched to process that request. If the request is processed
synchronously, the thread that processes the request is blocked
while the request is being processed, and that thread cannot service
another request.
This might not be a problem, because the thread
pool can be made large enough to accommodate many blocked threads.
However, the number of threads in the thread pool is limited. In
large applications that process multiple simultaneous long-running
requests, all available threads might be blocked. This condition is
known as thread starvation. When this condition is reached, the Web
server queues requests. If the request queue becomes full, the Web
server rejects requests with an HTTP 503 status (Server Too Busy).
for "thread starvation" the best approach is using "Asynchronous
Methods". refer here for more information.
Try to use using block for your datacontext, to dispose them immediately after finishing with them.
Huge data amount in transaction: you should check your code.
May be you using too much data without need to all of them. For
example you transfer all object which you may need just one
properties of object. In this case use "projection"(refer here for
an example).
Also you may use "lazy loading" or "eager loading" base on you
scenarios. But please be noted that none of these are magic tool for
every scenario. In some cases "lazy loading" improve performance and
on others "eager loading" makes things faster. It depends to your
deep understanding of these two terms and also your case of issue,
your code and your design.
Filter your data on server side or client side. Filtering data on server side helps to keep your server load and network traffic as less as possible. It also makes your application more responsive and with better performance. Use IQueryable Interface for server side filtering (check here for more information).
One side effect of using server side filtering is having better security
Check your architecture to see do you have any bottleneck. A
controller which gets called too much, a methods which handles lots
of objects with lots of data, a table in database which receives
requests continuously, all are candidates for bottle neck.
Ues cashing data when applicable for most requested data. But again
use cashing wisely and based on your situation. Wrong cashing makes
your server very slow.
If you think your speed issue is completely on your database, the best approach is using sql profiling tools to find out which point you have critical situation. Maybe redesign of your own tables could be an answer. Try to separate reading and writing tables as much as possible. Separation could be done by creating appropriate views. Also check this checklist for monitoring your database.

Achieving the same performance that Node.JS provides in an ASP.NET MVC application

This is what we see on the Node.JS website
Node.jsĀ® is a platform built on Chrome's JavaScript runtime for easily
building fast, scalable network applications. Node.js uses an
event-driven, non-blocking I/O model that makes it lightweight and
efficient, perfect for data-intensive real-time applications that run
across distributed devices.
Is it possible to develop non-blocking applications with ASP.NET MVC and get the same performance (handle the same number of requests per second and process them)?
Using async/await in the ASP.NET MVC controllers help to get the same performance (handle the same number of requests per second and process them) that a Node.JS application also provide?
Is it possible to develop non-blocking applications with ASP.NET MVC and get the same performance (handle the same number of requests per second and process them)?
Technically, this question is invalid, since there will probably be some load patterns / server configurations / state management setups that Node.js will be faster at, and some that ASP.NET will be faster at.
From an architecture perspective, yes, async/await gives you a similar approach to handling requests as Node.js, with one important difference. Node.js is strictly single-threaded (only using its thread pool for offloading work that would be done asynchronously if an asynchronous API existed for it). So, it will only execute application code for a single request at a time. ASP.NET follows a more complex model: it can be both parallel and asynchronous simultaneously.
In other words, Node.js uses single-threaded asynchrony, while ASP.NET uses multi-threaded asynchrony.
So, I'd expect Node.js and ASP.NET to both perform similarly on a single-core processor, with ASP.NET doing better on a multi-core (a common Node.js approach to multi-core is to run multiple instances of Node with a load balancer in front, but then caching and server state gets slower). Of course, there's only one way to test how they'll both perform for your application: write a reasonable test case and run it.

Where to initiate and manage background operations in Asp.Net MVC

The first operation will be carrying out several calculations and updating the same tables that users also access. These processes dont depend on any indivual request/state and will always be running.
Should I put the first operation in a separate application/machine?
The second operation acts like a manager across all requests and will be running continuously.
How do I initiate and maintain the second operation? Do I start an Admin request or can I initiate at a global level automatically?
This post (https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/) explains how to implement scheduled/background tasks with asp.net mvc. Otherwise you can use Windows Services or WCF services. You can use DB tables to synchronize background jobs with requests.
You don't need a separate application/machine but it depends on your requirements, your architecture (single server or farm) and your performance goals.

What are useful tips for making multi-core optimised ASP.NET MVC applications?

I see a lot of the multi-core information on the web applied to desktop applications - but I am interested: what tips and pointers would be useful for ASP.NET MVC web developers building applications that make the most of multiple cores/processors?
Leave it to the web server
I wouldn't mess with it in a web application unless it does some sort of processor heavy processing. Make sure your application performs well and leave processor(s) utilization to the web server to serve requests with all cores in the system.
If you have multiple long running processes per request, you could parallelize them. But generally it's not worth the coding effort and bugs that could show up.
In practice, just make each request lean, and then you can handle more requests at one time.
I don't think a web app gets as much value from multi-core/multi-threading as a desktop app, because ultimately each HTTP request is synchronous (except for AJAX, but each AJAX request is still an HTTP request). Certainly a server with multi-core is a good thing, and can probably handle requests faster, but I don't think there's much (in general) you can do with a multi-threading app that ultimately renders an HTML document.

Resources