我有以下 Controller :
[TimeoutFilter]
public abstract class BaseController: Controller
{
}
public class IntegrationTestController : BaseController
{
[HttpGet]
public ActionResult TimeoutSeconds()
{
return Content(HttpContext.Server.ScriptTimeout.ToString(CultureInfo.InvariantCulture));
}
[HttpGet]
public ActionResult ForceTimeout()
{
var timeoutWindow = TimeoutFilter.TimeoutSeconds;
Thread.Sleep((timeoutWindow + 5) * 1000);
return Content("This should never get returned, mwahahaaa!");
}
}
对于我的测试场景,我在 TimeoutFilter
中使用了 5 秒的配置设置,我知道这是有效的,因为当我的测试调用 TimeoutSeconds
时,我得到了正确的值为 5,但是当测试调用 ForceTimeout
时,我得到 200 的 HTTP 响应和我的“永不返回”文本。
过滤器:
public class TimeoutFilter : ActionFilterAttribute
{
internal const string TimeoutSecondsSettingsKey = "MvcActionTimeoutSeconds";
internal static int TimeoutSeconds;
public TimeoutFilter()
{
TimeoutSeconds = int.Parse(ConfigurationManager.AppSettings[TimeoutSecondsSettingsKey]);
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.ControllerContext.HttpContext.Server.ScriptTimeout = TimeoutSeconds;
base.OnActionExecuting(filterContext);
}
}
最佳答案
我无法通过设置 ScriptTimeout
来让它工作属性,即使在设置 debug="false"
时也是如此在web.config
正如用户 Erik Funkenbusch 所建议的那样:
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.5"/>
...
它继续返回文本“This should never get returned”而不是在 Thread.Sleep
期间超时.
还值得注意的是,我还扩展了 Thread.Sleep
远远超出Server.ScriptTimeout
默认为 110 秒,但它最终仍会返回相同的文本而不是超时。
然后我改为尝试设置 executionTimeout
在web.config
:
<configuration>
<system.web>
<httpRuntime targetFramework="4.5" executionTimeout="5"/>
...
如果您现在要将断点添加到 TimeoutFilter
你会观察到 ScriptTimeout
值已设置为 executionTimeout
来自 web.config
的值. las,这对我仍然不起作用(无论是否 debug="false"
)。
然后我遇到了 this link关于ScriptTimeout
和 executionTimeout
没有使用与您描述的类似的设置。帖子中的第一个回复描述了使用 debug="false"
并且还提到超时将有 5 到 15 秒的延迟。即使使用大 Thread.Sleep
我仍然没有运气值(value)。本文中的第二个回复表明 executionTimeout
配置设置是 ScriptTimeout
的替代品属性(显然是经典 ASP 中使用的 COM 接口(interface))。此回复表明,如果不使用您自己的超时逻辑,则无法设置特定的超时。
此外,我还遇到了 following (more recent) link第一个回复表明 MVC 中的超时已关闭。进一步的回复表明这是因为 MVCHandler
(选择将处理 HTTPRequest
的 Controller )是一个 IHttpAsyncHandler
因此,由于它可能正在执行另一个请求(这是使用异步请求的要点),因此它会在内部关闭超时状态(这是我从阅读此链接中收集到的信息)。它必须直接使用 asp.net
虽然使用 ScriptTimeout
似乎是 this answer 中接受的方式.
该链接表明添加以下行将允许它工作(但不适用于中等信任的应用程序):
System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);
因此,更改 TimeoutFilter
OnActionExecuting()
到:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);
base.OnActionExecuting(filterContext);
}
并设置 web.config
:
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5" executionTimeout="5"/>
...
允许超时工作,但有第一篇文章中提到的轻微 5 秒延迟。
注意:使用此方法不允许您设置 ScriptTimeout
过滤器中的属性。试图设置 ScriptTimeout
并覆盖 web.config
中设置的值似乎不起作用。
关于asp.net-mvc - 为什么我的操作方法没有超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27170151/