asp.net-mvc - 为什么我的操作方法没有超时?

标签 asp.net-mvc asp.net-mvc-4 http

我有以下 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 秒,但它最终仍会返回相同的文本而不是超时。

然后我改为尝试设置 executionTimeoutweb.config :

<configuration>
   <system.web>
      <httpRuntime targetFramework="4.5" executionTimeout="5"/>
      ...

如果您现在要将断点添加到 TimeoutFilter你会观察到 ScriptTimeout值已设置为 executionTimeout来自 web.config 的值. las,这对我仍然不起作用(无论是否 debug="false" )。

然后我遇到了 this link关于ScriptTimeoutexecutionTimeout没有使用与您描述的类似的设置。帖子中的第一个回复描述了使用 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/

相关文章:

c# - Entities Framework 6 alpha 2 - 异步模式

http - HTTP 文件上传如何处理大文件?

c# - MVC ASP.NET 网站的点击计数器

jquery-validate - ASP.NET MVC4中的条件验证

javascript - 使用 ajax 时 asp mvc 显示不更新

java - 将 Java 对象字段转换为 URI 中的查询参数

c# - 使用 Entity Framework 时出现 InvalidCastException

asp.net-mvc - 相同的 DataAnnotation 属性在相同的属性上重复

asp.net-mvc - MVC ViewData 是如何工作的?

asp.net - 在不使用 TempData 的成功 POST 请求后重定向后显示消息