在IIS中创建的线程可以通知其超时吗?

时间:2013-12-30 11:24:20

标签: c# asp.net multithreading iis

我们在Web应用程序中有一个长时间运行的过程。该过程在使用以下创建的单独线程上运行:

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

由于IIS限制无人值守线程可以运行多长时间,线程终止。它会因会话超时或应用程序回收而终止。

我想知道线程是否可以通知它即将超时。或者在被终止之前发送通知?

1 个答案:

答案 0 :(得分:0)

我创建了一个至少适用于WebDevServer的辅助类,我认为它也适用于IIS。它的作用是Register一个hostingenvironment的助手,当主机被很好地取下时,它最终会调用Stop。请记住,如果不受控制的进程退出,则不再运行任何线程,因此也不会调用此方法。

<强>用法

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

<强>辅助

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
    }
}