我创建了一个C#应用程序,使用Microsoft.Web.Administration.ApplicationPool类一次一个地回收IIS中的所有应用程序池。 ApplicationPool上没有方法可以重新启动应用程序池(如果我错了,请纠正我),所以我想你只需要停止,然后开始。这在大多数情况下工作正常,直到我们开始在应用程序池中获得一些陷入无限循环的线程。
默认情况下,IIS有一个90秒的“关闭时间限制”,在它终止任何仍在运行的线程之前等待90秒,所以我会调用ApplicationPool.Stop(),直到IIS终止它需要90秒应用程序池,在它的状态将被停止之前,我可以告诉它重新开始。任何试图使用该应用程序池命中任何应用程序的东西都会在90秒内收到503错误响应,直到我再次启动该池。
我决定尝试以编程方式将“关闭时间限制”更改为5秒,以减少将导致503错误的应用程序数量,但IIS仍会在终止应用程序池之前等待90秒。以下是我关闭应用程序池的功能:
private void StopAppPool(ApplicationPool applicationPool)
{
ObjectState state = applicationPool.State;
TimeSpan previousShutdownTimeLimit = applicationPool.ProcessModel.ShutdownTimeLimit;
applicationPool.ProcessModel.ShutdownTimeLimit = new TimeSpan(0, 0, 5);
switch (state)
{
case ObjectState.Started:
applicationPool.Stop();
WL("Application Pool {0}'s state has gone from {1} to {2}", applicationPool.Name, state, applicationPool.State);
break;
case ObjectState.Starting:
case ObjectState.Unknown:
for (int i = 0; i < 180; i++)
{
WL("Application Pool {0}'s state is {1}. Waiting for state to become Started", applicationPool.Name, state);
Thread.Sleep(500);
state = applicationPool.State;
if (applicationPool.State == ObjectState.Started) { break; }
}
if (state == ObjectState.Started)
{
applicationPool.Start();
WL("Application Pool {0}'s state has gone from {1} to {2}", applicationPool.Name, state, applicationPool.State);
}
else
{
WL("Error starting Application Pool {0}: Application Pool never stopped", applicationPool.Name);
}
break;
case ObjectState.Stopped:
case ObjectState.Stopping:
WL("Application Pool {0} was already in a {1} state and has not been modified", applicationPool.Name, state);
break;
default:
WL("Error stopping Application Pool {0}: Unexpected ObjectState \"{1}\"", applicationPool.Name, state);
break;
}
state = applicationPool.State;
for (int i = 0; i < 180 && state != ObjectState.Stopped; i++)
{
WL("Application Pool {0}'s state is {1}. Waiting for state to become Stopped", applicationPool.Name, state);
Thread.Sleep(500);
state = applicationPool.State;
}
applicationPool.ProcessModel.ShutdownTimeLimit = previousShutdownTimeLimit;
}
为什么ApplicationPool.ProcessModel.ShutdownTimeLimit似乎不会影响IIS实际终止应用程序池所需的时间?在我尝试回收应用程序池时,是否还有其他应用程序不接收503错误?
答案 0 :(得分:7)
为了让Recycle the App Pool终止进程并遵守ApplicationPool.ProcessModel.ShutdownTimeLimit属性,您必须采取以下步骤:
在回收ApplicationPool时,IIS有点奇怪,因为新的w3wp.exe ApplicationPool进程将立即启动,但旧的应用程序池将等待ApplicationPool.ProcessModel.ShutdownTimeLimit中的秒数关闭。然后它会将仍在运行的任何内容移动到新进程。但是如果你再次回收它,它将杀死无限循环(在ShutdownTimeLimit中等待适当的时间之后)。
所以总结一下,正确地提交你的更改,等待它们生效,然后执行你的回收,如果你有一个你想要杀死的无限循环,那就再做一次。
我在我的博客上发布了源代码和最终可执行文件here。
答案 1 :(得分:2)