使用IRegisteredObject时强制卸载Appdomain

时间:2015-02-25 21:33:33

标签: c# asp.net iis

我们有一些在IIS ASP.NET网站上运行的后台进程。为了防止这些进程在应用程序回收时死亡,我们实现了一个IRegisteredObject实例,我们在卸载appdomain之前等待服务器上的工作完成(参见下面的设计示例)。

我们的代码按预期工作,但是当我们进行部署时 - 旧的应用程序域仍然存在,直到我们想要的工作完成(我们想要) - 但是,经常部署/大量工作 - 我们遇到资源问题我们的虚拟机几乎耗尽了。

是否存在强制卸载的外部方式(无论IRegisteredObject存在)/杀死较旧的appdomains?或者我们可以与旧的appdomain通信以告诉它在代码中终止的方式?

internal class ShutdownHelper : IRegisteredObject
{
    public ShutdownHelper() {
        HostingEnvironment.RegisterObject(this);
    }

    void IRegisteredObject.Stop(bool immediate)
    {
        if (immediate)
        {
            WaitForAllWorkToComplete(TIMEOUT /* Some arbitrary timeout*/); // This function returns when all processing on the server has completed
            HostingEnvironment.UnregisterObject(this);
        }
        else
        {
            // Similar logic as immediate but run asynchronously and we only unload if the task completes (in a continuation)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您可以使用此段代码Enumerating AppDomains

枚举所有域名

然后,您可以使用AppDomain.CreateInstanceAndUnwrap方法在远程AppDomain上执行代码。域应该包含加载了此共享类型的程序集。

    CrossAppDomainExecuteStopper stopper = (CrossAppDomainExecuteStopper)appDomain.CreateInstanceAndUnwrap(typeof(CrossAppDomainExecuteStopper).Assembly.FullName, typeof(CrossAppDomainExecuteStopper).FullName);
    stopper.StopWork();

CrossAppDomainExecuteStopper必须继承自MarshalByRefObject

public class CrossAppDomainExecuteStopper : MarshalByRefObject
{
    public void StopWork()
    {
        // force stop the work
    }
}