If I write this code
protected void Page_Load(object sender, EventArgs e)
{
Page_Load(sender, e);
}
I get the an Error (endless recursion):
and the w3wp.exe process is terminated from task manager.
Fine...
however if i do:
throw new ApplicationException(); //or SystemException();
it appears in just a regular exception page. ( w3wp.exe is still up).
questions :
what kind of exceptions causing the w3wp.exe to shutdown ?
what kind of exceptions causing the Application Pool to shutdown ?
p.s.
according to what ive just written , please think about the following scenario :
i can write a web page , host my site in a farm of sites , and i can terminate the whole w3wp.exe process by creating recursion ..... ( also others will have trouble)...
Can you please answer my questions ?
thanks.
This is most likely the famous StackoverflowException. It's caused by an infinite loop since you're calling the method Page_Load again and again.
From MSDN:
In prior versions of the .NET Framework, your application could catch
a StackOverflowException object (for example, to recover from
unbounded recursion). However, that practice is currently discouraged
because significant additional code is required to reliably catch a
stack overflow exception and continue program execution.
Starting with the .NET Framework version 2.0, a StackOverflowException
object cannot be caught by a try-catch block and the corresponding
process is terminated by default. Consequently, users are advised to
write their code to detect and prevent a stack overflow. For example,
if your application depends on recursion, use a counter or a state
condition to terminate the recursive loop. Note that an application
that hosts the common language runtime (CLR) can specify that the CLR
unload the application domain where the stack overflow exception
occurs and let the corresponding process continue. For more
information, see ICLRPolicyManager Interface and Hosting Overview.
You may want to have a look at this answer:
https://stackoverflow.com/a/4802309/284240
The reason for the exception is memory overflow. There are many ways how an application can cause this, there is no point to guess specific scenarios. I imaging good hosting providers should be protected from misbehaving applications.
to add to the answers which alrdy are available. u cant bring down the whole process because every website in a server runs in a seperate AppDomain. so if ur code misbehaves only ur appdomain wud be killed.
Related
I have an ASP.Net website that has custom internal threads, for periodically occurring tasks.
If I get an exception on one of these threads, it is not caught in Global.ASAX's Application_Error() function. It is allowed to bubble up to IIS and I find out about it by reviewing the Event Viewer logs. If I catch the exception then Log4Net will direct an email to me and I should find out about the error relatively quickly.
Is there a way I can trap exceptions on these threads? The app needs to be 'always-on', so an exception that drops the application is a show-stopper.
In a comment you mentioned:
This is a web-site rather than web app.
"Web site" vs. "web app" seems like a moot distinction at this point. There's enough complexity in the code that it's an "application" by pretty much any definition of the word. To that point, if the application host doesn't meaningfully manage thread faults for you (and I wouldn't expect a web application host to do so) then you have to manage them manually.
In this case I see that as one of two options:
Option 1: Don't let your threads end in a faulted state. Whatever your top-level worker item for any given thread is (a method invoked at the start of the thread, a loop repeating operations, etc.), that needs to be essentially fault-proof. No exception should get past that. Which means it needs to be dead simple (so as to not throw exceptions of its own) and needs to catch any and all exceptions from the operation(s) it invokes.
Once caught, do with them as you please. Roll back a unit of work, notify someone of the error, etc.
Option 2: Move the long-running thread operations out of the web application, since web applications aren't really suited for ongoing background processes. A Windows Service or scheduled Console Application is a much more suited application host for that logic.
Yes, bit of a re-write there though.
Is it? It shouldn't be. That's really a matter of how the code was originally architected, not related to the application hosts themselves. Invoking a business operation from one application host is the same as invoking it from another. If the logic is tightly coupled to the application technology, that's a separate problem. And there's no quick fix to that problem. The good news is that once you fix that problem, other problems (like the one which prompted this question) are quick fixes.
I need to execute an infinite while loop and want to initiate the execution in global.asax.
My question is how exactly should I do it? Should I start a new Thread or should I use Async and Task or anything else? Inside the while loop I need to do await TaskEx.Delay(5000);
How do I do this so it will not block any other processes and will not create memory leaks?
I use VS10,AsyncCTP3,MVC4
EDIT:
public void SignalRConnectionRecovery()
{
while (true)
{
Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString());
await TaskEx.Delay(5000);
}
}
All I need to do is to run this as a singleton instance globally as long as application is available.
EDIT:SOLVED
This is the final solution in Global.asax
protected void Application_Start()
{
Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery);
signalRConnectionRecovery.IsBackground = true;
signalRConnectionRecovery.Start();
Application["SignalRConnectionRecovery"] = signalRConnectionRecovery;
}
protected void Application_End()
{
try
{
Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"];
if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive)
{
signalRConnectionRecovery.Abort();
}
}
catch
{
///
}
}
I found this nice article about how to use async worker: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx
And this:
http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6
But I think for my needs this one will be perfect:
http://forums.asp.net/t/1433665.aspx/1
ASP.NET is not designed to handle this kind of requirement. If you need something to run constantly, you would be better off creating a windows service.
Update
ASP.NET is not designed for long running tasks. It's designed to respond quickly to HTTP requests. See Cyborgx37's answer or Can I use threads to carry out long-running jobs on IIS? for a few reasons why.
Update
Now that you finally mentioned you are working with SignalR, I see that you are trying to host SignalR within ASP.NET, correct? I think you're going about this the wrong way, see the example NuGet package referenced on the project wiki. This example uses an IAsyncHttpHandler to manage tasks.
You can start a thread in your global.asax, however it will only run till your asp.net process get recycled. This will happen at least once a day, or when no one uses of your site. If the process get recycled, the only way the thread is restarted agian, is when you have a hit on your site. So the thread is not running continueuosly.
To get a continues process it is better to start a windows service.
If you do the 'In process' solution, it realy depends on what your are doing. The Thread itself will not cause you any problems in memory or deadlocks. You should add a meganism to stop your thread when the application stops. Otherwise restarting will take a long time, because it will wait for your thread to stop.
This is an old post, but as I was seraching for this, I would like to report that in .NET 4.5.2 there is a native way to do it with QueueBackgroundWorkItem.
Take a look at this post: https://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/
MarianoC
It depends what you are trying to accomplish in your while loop, but in general this is the kind of situation where a Windows Service is the best answer. Installing a Windows Service is going to require that you have admin privileges on the web server.
With an infinite loop you end up with a lot of issues regard the Windows message pump. This is the thing that keeps a Windows application alive even when the application isn't "doing" anything. Without it, a program simply ends.
The problem with an infinite loop is that the application is stuck "doing" something, which prevents other applications (or threads) from "doing" their thing. There have been a few workarounds, such as the DoEvents in Windows Forms, but they all have some serious drawbacks when it comes to responsiveness and resource management. (Acceptable on a small LOB application, maybe not on a web server.) Even if the while-loop is on a separate thread, it will use up all available processing power.
Asynchronus programming is really designed more for long-running processes, such as waiting for a database to return a result or waiting for a printer to come online. In these cases, it's the external process that is taking a long time, not a while-loop.
If a Window Service is not possible, then I think your best bet is going to be setting up a separate thread with its own message pump, but it's a bit complicated. I've never done it on a web server, but you might be able to start an Application. This will provide a message pump for you and allow you to respond to Windows events, etc. The only problem is that this is going to start a Windows application (either WPF or WinForms), which may not be desirable on a web server.
What are you trying to accomplish? Is there another way you might go about it?
I found this nice article about how to use async worker, will give it a try. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx
And this:
http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6
But I think for my needs this one will be perfect:
http://forums.asp.net/t/1433665.aspx/1
I thought I read somewhere that the WebRole runs in a different process than IIS on Windows Azure, making it possible to combine both Web and Worker roles http://things.smarx.com/#Combine%20Web%20and%20Worker%20Roles
Assuming the following generic code:
public class WebRole : RoleEntryPoint
{
public override void Run()
{
... Exception gets thrown here.
}
}
Does this require a separate exception handling approach?
Is the Run different than OnStart, meaning certain services have been started?
Any best practices?
The title of the question and the inline question are different - which one are you most concerned about?
The WebRole in 1.3+ SDK can run full IIS, which runs under a different process than the RoleEntryPoint. This means for exception handling purposes, the RoleEntryPoint and the IIS web app are totally isolated. You would need explicit error handling in each as one does not apply to the other.
The other question you asked has to do with the Run vs OnStart. The OnStart method is called before your instance is connected to the LoadBalancer. This is your chance to bootstrap the role with anything you need to do before active traffic hits it. You must return true and not throw an error in OnStart or you will never get an active instance. Some folks use the OnStart to programmatically create the IIS stuff they need (sites, apps, vdirs, etc.). The Run method is your entry point to the main worker logic. It is like static void Main() (but one you never exit from).
The reality is that the Web and Worker roles are pretty much identical with the sole exception that the Web role has some nice declarative syntax now to setup IIS for you. All other caveats of runnig in a worker role apply to the web role when using the RoleEntryPoint.
RoleEntyPoint gets intialized before ASP.Net runtime is intitialized. As far as i remember if Run method throws exception the role would recycle,and you can see that in your Azure management portal. See this for some hints.
In my 3.5 .net web application I have a background thread that does a lot of work (the application is similar to mint.com in that it does a lot of account aggregation on background threads). I do extensive exception handling within the thread performing the aggregation but there's always the chance an unhandled exception will be thrown and my entire application will die. I've read some articles about this topic but they all seem fairly outdated and none of them implement a standard approach. Is there a standard approach to this nowadays? Is there any nicer way to handle this in ASP.NET 4.0?
Arguably, the entire application should die if you have an unhandled exception. An unhandled exception means that your program is in an unknown/indeterminate state, and any further processing or user interaction could cause corruption of the program's state, or worse, data corruption.
You're doing the right thing handling exceptions within your thread work. As far as I know, there is no way for a .NET application to "gracefully" deal with unhandled exceptions on background threads - they will always terminate the process.
Certain .NET Framework classes, such as the BackgroundWorker component and the Task Parallel Library in .NET 4 make multithreading easier and handle a lot of the dirty work of exception handling for you, so if it's possible for you to use those instead of implementing your own multi-threaded code, then you should definitely do so. But if those aren't able to help you in a given circumstance, if you must use the ThreadPool or a pure Thread, then be sure not to let any unhandled exceptions escape.
You can always put a try/catch block around your worker thread at a very high level... like right when the thread starts. I'm assuming this is what you're doing already, or something like it. But just keep in mind that you definitely don't want to turn an unknown error into a silent unknown error, because then it's going to be much harder to track down when something goes wrong. Be sure you are logging the exception to the EventLog or your custom app log if you want to just catch it and forget it.
Like Aaronaught says, the application should die when something unexpected happens. But I don't see a problem with just letting your background thread exit/die instead of bringing down the whole application process (in fact, I don't think Aaron is correct here, it won't kill the entire process) I think your question can basically be translated as "is there something magical in ASP.NET that will suddenly solve issues I don't even know about yet?" and the answer to that of course, is no. But you already knew that. :)
I admit it: I don't bother with too much exception handling. I know I should do more but I can never wrap my head around where to start and where to stop. I'm not being lazy. Far from it. It's that I'm overwrought with exception handling ambivalence. It just seems that there is a seemingly infinite number of places in even the smallest app where exception handling can be applied and it can begin to feel like overkill.
I've gotten by with careful testing, validating, and silent prayer but this is a bad programming accident waiting to happen.
So, what are your exception handling best practices? In particular, where are the most obvious/critical places where exception handling should be applied and where are places where it should be considered?
Sorry for the vague the question but I really want to close the book on this once and for all.
Microsoft's Patterns & Practices team did a good job incorporating best practices of exception management into Enterprise Library Exception Handling Application Block
Event if wouldn't use Enterprise Library, I highly recommend you to read their documentation. P&P team describes common scenarios and best practices for exceptions handling.
To get you started I recommend read following articles:
Exception Handling on MSDN
Exception Management in .NET on MSDN
Exception Handling Best Practices in .NET on CodeProject
ASP.NET specific articles:
User Friendly ASP.NET Exception Handling
Global Exception Handling with
ASP.NET
Exception handling in C# and ASP
.Net
The golden rule with exception handling is:
"Only catch what you know how to handle"
I've seen too many try-catch blocks where the catch does nothing but rethrow the exception. This adds no value. Just because you call a method that has the potential to throw an exception doesn't mean you have to deal with the possible exception in the calling code. It is often perfectly acceptable to let exceptions propagate up the call stack to some other code that does know what to do.
In some cases, it is valid to let exceptions propagate all the way up to the user interface layer then catch and display the message to the user. It might be that no code is best-placed to know how to handle the situation and the user must decide the course of action.
I recommend you start by adding a good error page that catches all exceptions and prints a slightly less unfriendly message to the user. Be sure to log all details available of the exception and revise that. Let the user know that you have done this, and give him a link back to a page that will (probably) work.
Now, use that log to detect where special exception handling should be put in place. Remember that there is no use in catching an exception unless you plan to do something with it. If you have the above page in place, there is no use in catching database exceptions individually on all db operations, unless you have some specific way to recover at that specific point.
Remember: The only thing worse than not catching exceptions, is catching them and not doing nothing. This will only hide the real problems.
Might be more about exception handling in general than ASP.NET speific but:
Try to catch exceptions as close to
the cause as possible so that you
can record (log) as much information
about the exception as possible.
Include some form of catch all, last
resort exception handler at the
entry points to your program. In
ASP.NET this could be the
Application level error handler.
If you don't know how to "correctly" handle an exception let it bubble up to the catch all handler where you can treat it as an "unexpected" exception.
Use the Try***** methods in .NET
for things like accessing a
Dictionary. This helps avoid major
performance problems (exception
handling is relatively slow) if you
throw multiple exceptions in say a
loop.
Don't use exception handling to
control normal logic of your
program, e.g. exiting from a loop via
a throw statement.
Start off with a global exception handler such as http://code.google.com/p/elmah/.
Then the question comes down to what kind of application are you writting and what kind of user experience do you need to provide. The more rich the user experience the better exception handling you'll want to provide.
As an example consider a photo hosting site which has disk quotas, filesize limits, image dimension limits, etc. For each error you could simply return "An error has occured. Please try again". Or you could get into detailed error handling:
"Your file is to large. Maximum
filesizes is 5mb."
"Your image is is
to large. Maximum dimensions are
1200x1200."
"Your album is full.
Maximum storage capacity is 1gb".
"There was an error with your
upload. Our hampsters are unhappy.
Please come back later."
etc. etc.
There is no one size fits all for exception handling.
Well at the very basic level you should be handling the HttpApplication.Error event in the Global.asax file. This should log any exception that occurs to a single place so you can review the stack trace of the exception.
Apart from this basic level you should ideally be handling exceptions where you know you can recover from them - for example if you expect a file might be locked then handling the IOException and reporting the error back to the user would be a good idea.