为什么我的操作方法超时? [英] Why doesn't my action method time out?

查看:186
本文介绍了为什么我的操作方法超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下控制器:

  [TimeoutFilter]
公共抽象类BaseController:控制器
{
}公共类IntegrationTestController:BaseController
{
    [HTTPGET]
    公众的ActionResult多少秒()
    {
        返回内容(HttpContext.Server.ScriptTimeout.ToString(CultureInfo.InvariantCulture));
    }    [HTTPGET]
    公众的ActionResult ForceTimeout()
    {
        VAR timeoutWindow = TimeoutFilter.TimeoutSeconds;
        Thread.sleep代码((timeoutWindow + 5)* 1000);
        返回的内容(这应该永远不会回来,mwahahaaa!);
    }
}

有关我的测试场景我用5秒的配置设置在 TimeoutFilter ,我知道这是工作,因为当我的测试呼叫多少秒,我得到的5正确的值,但是当测试呼叫 ForceTimeout ,我得到的200和我的'再也没有回来文本HTTP响应。

和过滤器:

 公共类TimeoutFilter:ActionFilterAttribute
{
    内部常量字符串TimeoutSecondsSettingsKey =MvcActionTimeoutSeconds;
    内部静态INT多少秒;
    公共TimeoutFilter()
    {
        多少秒= int.Parse(ConfigurationManager.AppSettings [TimeoutSecondsSettingsKey]);
    }    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ControllerContext.HttpContext.Server.ScriptTimeout =多少秒;
        base.OnActionExecuting(filterContext);
    }
}


解决方案

我不能设置时,得到这个由要么设置 ScriptTimeout 属性,甚至上班调试=false的的web.config 由用户埃里克Funkenbusch建议:

 <结构>
   <&的System.Web GT;
      <编译调试=假targetFramework =4.5/>
      ...

它继续返回文本这应该永远不会回来,而不是在超时的 Thread.sleep代码

这也是值得注意的是,我还延长了 Thread.sleep代码来,远远超出了 Server.ScriptTimeout 默认110秒,但它仍然最终回到相同的文本,而不是超时。

然后我,而不是试图设置 executionTimeout 的web.config

 <结构>
   <&的System.Web GT;
      <的httpRuntime targetFramework =4.5executionTimeout =10/>
      ...

如果你现在一个断点添加到 TimeoutFilter ,你会观察到 ScriptTimeout 值已设置从 web.config中的 executionTimeout 。唉,这仍然没有为我工作(无论是否调试=false的)。

然后我遇到关于<$此链接 C $ C> ScriptTimeout 和 executionTimeout 不能用类似的设置,以你描述的工作。在后的第一个答复介绍如何使用调试=false的还提到,超时将有5至15秒的延迟。采用大 Thread.sleep代码价值,甚至当我还没有运气。本文中的第二个答复表明, executionTimeout 配置设置是一个替换 ScriptTimeout 属性(这显然是一个在传统的ASP使用的COM接口)。此回复表明这是不可能的设置特定的超时,而不使用自己的超时逻辑。

此外,我然后通过来到下(最近)链接,其中第一答复表明,超时在MVC的关闭。进一步的答复表明,这是因为<一href=\"http://msdn.microsoft.com/en-us/library/system.web.mvc.mvchandler%28v=vs.118%29.aspx\"><$c$c>MVCHandler (其中选择将要处理的控制器中的 HTT prequest )是 IHttpAsyncHandler 键,因为它可能会因此受到执行另一个请求(这是用一个异步请求的点),因此它在内部切换时间出状态了(这是我收集来自阅读本链接)。它必须以直 asp.net工作虽然与使用 ScriptTimeout 似乎是在的this回答

链接表明,加入以下一行将允许它运行(而不是在一个中等信任的应用程序):

  System.Web.HttpContext.Current.GetType()getfield命令(_ timeoutState,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)。.SetValue(系统.Web.HttpContext.Current,1);

因此​​,改变 TimeoutFilter OnActionExecuting()来:

 公共覆盖无效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

 &LT;结构&gt;
   &LT;&的System.Web GT;
      &LT;编译调试=假targetFramework =4.5/&GT;
      &LT;的httpRuntime targetFramework =4.5executionTimeout =10/&GT;
      ...

允许超时工作,但具有在第一篇文章中提到的轻微5秒延迟。

注意:使用此方法不允许您设置 ScriptTimeout 属性过滤器。试图设置 ScriptTimeout 和覆盖 web.config中设置的值不出现工作。

I have the following controllers:

[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!");
    }
}

For my test scenario I use a config setting of 5 seconds in the TimeoutFilter, and I know this is working because when my test calls TimeoutSeconds, I get the correct value of 5, but when the test calls ForceTimeout, I get an HTTP response of 200 and my 'never returned' text.

And the filter:

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);
    }
}

解决方案

I could not get this to work by setting the ScriptTimeout property either, even when setting the debug="false" in the web.config as suggested by user Erik Funkenbusch:

<configuration>
   <system.web>
      <compilation debug="false" targetFramework="4.5"/>
      ...

It continued to return the text "This should never get returned" rather than timing out during the Thread.Sleep.

It is also worth noting that I also extended the Thread.Sleep to well beyond the Server.ScriptTimeout default of 110 seconds but it still eventually returned the same text rather than timing out.

I then instead tried to set executionTimeout in the web.config:

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

If you were to now add a breakpoint to the TimeoutFilter you will observe that the ScriptTimeout value has been set to the executionTimeout value from web.config. Alas, this still did not work for me (regardless of whether debug="false").

I then came across this link about ScriptTimeout and executionTimeout not working with a similar setup to what you describe. The first reply in the post describes using the debug="false" and also mentions that the timeout will have a delay of 5 to 15 seconds. I still had no luck even when using a large Thread.Sleep value. The second reply in this article suggests that the executionTimeout config setting is a replacement of the ScriptTimeout property (which is apparently a COM interface used in classic ASP). This reply suggests that is not possible to set a specific timeout without using your own time-out logic.

Further, I then came across the following (more recent) link where the first reply suggests that the timeout is switched off in MVC. A further reply suggests that this is because an MVCHandler (which selects the controller that will handle the HTTPRequest) is an IHttpAsyncHandler and as it may therefore be executing another request (which is the point of using an async request) it therefore internally switches the time-out state off (this is what I gather from reading this link). It must work with straight asp.net though as using ScriptTimeout seems to be the accepted way in this answer.

The link suggests that adding the following line will allow it to work (but not in a medium trust application):

System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);

Therefore, changing the TimeoutFilter OnActionExecuting() to:

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);
}

and setting the web.config:

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

allows the time-out to work but has the slight 5 second delay that is mentioned in the first post.

Note: Using this method does not allow you to set the ScriptTimeout property in the filter. Trying to set ScriptTimeout and override the value set in web.config does not appear to work.

这篇关于为什么我的操作方法超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆