Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用IRegisteredObject时强制卸载Appdomain_C#_Asp.net_Iis - Fatal编程技术网

C# 使用IRegisteredObject时强制卸载Appdomain

C# 使用IRegisteredObject时强制卸载Appdomain,c#,asp.net,iis,C#,Asp.net,Iis,我们有一些在IIS ASP.NET网站上运行的后台进程。为了防止这些进程在应用程序回收时消亡,我们实现了一个IRegisteredObject实例,在该实例中,我们在卸载appdomain之前等待服务器上的工作完成(请参见下面的人为示例) 我们的代码按预期工作,但正如我们进行部署一样-旧的appdomains会一直存在,直到我们想要的工作完成(这是我们想要的)-然而,由于频繁的部署/大量的工作-我们遇到了虚拟机上的资源几乎耗尽的情况 是否有外部方法强制卸载(无论IRegisteredObject

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

我们的代码按预期工作,但正如我们进行部署一样-旧的appdomains会一直存在,直到我们想要的工作完成(这是我们想要的)-然而,由于频繁的部署/大量的工作-我们遇到了虚拟机上的资源几乎耗尽的情况

是否有外部方法强制卸载(无论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)
        }
    }
}

您可以使用这段代码枚举所有域

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

    CrossAppDomainExecuteStopper stopper = (CrossAppDomainExecuteStopper)appDomain.CreateInstanceAndUnwrap(typeof(CrossAppDomainExecuteStopper).Assembly.FullName, typeof(CrossAppDomainExecuteStopper).FullName);
    stopper.StopWork();
CrossAppDomainExecuteStop
必须继承自
MarshalByRefObject

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

当我尝试枚举appdomains时,我得到两个透明代理类型和一个应用程序域(我当前的appdomain)。我实际上如何从透明代理获取信息?我想至少看到他们的“FriendlyName”,这样我就可以确保停止在正确的应用程序域上工作。@Badazzindu我记得在调试模式下不会显示任何信息,但您可以在运行时访问FriendlyName。顺便说一句,我尝试了GetData/SetData,但数据无法通过appdomain:-/共享。如果需要共享信息,请尝试访问在appdomain中承载这些信息的静态类型。这将导致序列化异常。无法检索旧应用程序域的友好名称
[HttpGet]public ActionResult GetAppDomains(){var domains=AppDomainEnumerator.GetAppDomains();返回新的ContentResult(){Content=domains.Select(a=>a.FriendlyName.ToDelimitedString()};}
我还没有尝试它,但是如果您在
MarshalByRefObject
中返回
AppDomain.CurrentDomain.FriendlyName