3

We have a long running process in web application. The process runs on a seperate thread created using this:

var arguments = new object[] { startDate, endDate,  m_token };
ThreadPool.QueueUserWorkItem((WaitCallback)xyzmethod, arguments);

The thread is getting terminated due to limitation of IIS on how long an unattended thread can run. It gets terminated due to session timeout or application recycle.

I want to know if a thread can notify that it is about to timeout. Or send a notification just before getting terminated?

Vitor Canova
  • 3,918
  • 5
  • 31
  • 55
AvaMru
  • 31
  • 1
  • Notify what? If it's timed out and it's parent thread is timed out there is no process to notify. If the application is recycled then your completely screwed. It won't even have any warning that it's happening. It sounds like your looking at this the wrong way. What does this thread actually do? – Liam Dec 30 '13 at 11:46
  • 4
    You should read [Can I use threads to carry out long-running jobs on IIS?](http://stackoverflow.com/questions/536681/can-i-use-threads-to-carry-out-long-running-jobs-on-iis?rq=1) – Liam Dec 30 '13 at 11:52
  • 2
    The app pool can get recycled at any time for a variety of reason, some of which you have control over. You'd be better off running your long-duration work in its own process, perhaps NT service, and have your IIS app communicate with that instead. – Chris O Dec 30 '13 at 16:24

1 Answers1

0

I have an helper class created that works at least for the WebDevServer, I assume it works for IIS as well. What this does is it Register a helper with the hostingenvironment which ends up calling Stop when the host is nicely taken down. Remember that in case of an uncontrolled process exit no threads will run anymore so this method is also not being called.

Usage

    protected void Button1_Click(object sender, EventArgs e)
    {
        var hlp = Myhelper.Create();
        var arguments = new object[] { "foo", 42 };
        ThreadPool.QueueUserWorkItem(hlp.FooBar, arguments);
    }

Helper

public class Myhelper:IRegisteredObject
{
    private Myhelper(){}

    // factory
    public static Myhelper Create() 
    {
        var hlp = new Myhelper();
        HostingEnvironment.RegisterObject(hlp); // register ourself!
        return hlp; 
    }

    bool keepRunning = true;
    ManualResetEvent mre = new ManualResetEvent(false);
    ManualResetEvent stopped = new ManualResetEvent(false);

    // our DoWork method!
    public void FooBar(object args) 
    {
        EventLog.WriteEntry(".NET Runtime", "started");
        // implement your long running function, 
        // be sure to check regularly if you need to stop processing
        while (keepRunning)
        {
            Trace.Write("+");
            mre.WaitOne(1000); // do work, (used this instead of Thread.Sleep())
        }
        EventLog.WriteEntry(".NET Runtime","stopped");
        HostingEnvironment.UnregisterObject(this); 
        stopped.Set(); // we are done!
    }

    // this gets caled when the HostingEnvironment is stopping
    public void Stop(bool immediate)
    {
        keepRunning = false;
        mre.Set(); // signal nicely
        stopped.WaitOne(200); // wait max 200 ms before returning to prevent getting stuck
    }
}
rene
  • 41,474
  • 78
  • 114
  • 152