Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to IIS shutdown event in ASP.NET

Tags:

c#

asp.net

iis

I have in my ASP.NET static variable that flushes itself to DB every X insertions. Problem is, if I publish the application , the IIS process is killed with all my static material.

How can I preserve it - or how can I flush it once ASP.NET application is shutting down?

thank you

like image 576
Himberjack Avatar asked Jan 18 '11 11:01

Himberjack


4 Answers

Global.asax

void Application_End(object sender, EventArgs e) 
    {
        //  SHUTDOWN CODE HERE
    }
like image 110
Hawxby Avatar answered Nov 05 '22 19:11

Hawxby


As already stated, it is highly not recommended to have application persist large data during Application_End, as this might be triggered when application pool is shut down, not at the beginning of its shutting down. This is explained in more detailed (but still short) here.

If one still wants to catch the shutting down of an application pool for all cases that do not instantly kill it, can do the following:

Dirty way

1) Get shutdown time limit - IIS manager -> Application Pools -> -> Advanced settings ... -> Process model group -> Shutdown Time Limit (second)

2) Create an thread/task in the application to run twice as often as shutdown time limit to ensure that "shutting down" state can be caught. This thread should

i) check if application pool is shutting down

public bool IsShuttingDown()
{
    return System.Web.Hosting.HostingEnvironment.ShutdownReason != ApplicationShutdownReason.None;
}

ii) if shutting down is on, do your stuff. Ensure that stuff is executed only once

More correct way (as indicated here)

1) Create a class which implements IRegisteredObject

public class HostingEnvironmentRegisteredObject : IRegisteredObject
{
    // this is called both when shutting down starts and when it ends
    public void Stop(bool immediate)
    {
        if (immediate)
            return;

        // shutting down code here
        // there will about Shutting down time limit seconds to do the work
    }
}

2) Register your object (Global.asax.cs)

protected void Application_Start()
{
    // other initialization code here

    HostingEnvironment.RegisterObject(new HostingEnvironmentRegisteredObject());
}

3) Unregistering (source)

The Stop method is first called with the immediate parameter set to false. The object can either complete processing, call the UnregisterObject method, and then return or it can return immediately and complete processing asynchronously before calling the UnregisterObject method.

If the registered object does not complete processing before the application manager's time-out period expires, the Stop method is called again with the immediate parameter set to true. When the immediate parameter is true, the registered object must call the UnregisterObject method before returning; otherwise, its registration will be removed by the application manager.


As a side note, I will also include some details about implementing the same think within ASP.NET Core 2.x. This can be performed using IApplicationLifetime interface. Example (Startup.cs):

public void Configure(IApplicationLifetime lifetime)
{
    var quartz = new JobScheduler(Kernel);
    lifetime.ApplicationStarted.Register(quartz.Start);
    lifetime.ApplicationStopping.Register(quartz.Stop);
}

Note: this will work only when hosted within IIS (possible other Web servers), but not within IISExpress which will not trigger IApplicationLifetime functionality.

like image 29
Alexei - check Codidact Avatar answered Nov 05 '22 19:11

Alexei - check Codidact


Its kind of risky to rely on application shutdown events to keep a database updated. If IIS is force restarted, recycled or there is a power outage, then you are going to miss the event.

like image 42
djeeg Avatar answered Nov 05 '22 19:11

djeeg


You might not receive any notification that IIS is shutting down. Think of what will happen if the IIS AppPool crashes or what will happen if the server simply loses power.

You cannot rely on ever hearing about shutdown events. If IIS wants to shut down, it's not necessarily going to notify your application. I recommend you re-think your writebuffering/caching scenario - only keep in memory the data that you can afford to lose.

like image 3
Sander Avatar answered Nov 05 '22 18:11

Sander