Pro*_*ofK 17 asp.net-mvc http asp.net-mvc-4
我有以下控制器:
[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!");
}
}
Run Code Online (Sandbox Code Playgroud)
对于我的测试场景,我使用了5秒的配置设置TimeoutFilter
,我知道这是有效的,因为当我的测试调用时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);
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ous 13
我不能让这通过设置工作的ScriptTimeout
任一属性,设置,即使debug="false"
在web.config
用户埃里克Funkenbusch的建议:
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.5"/>
...
Run Code Online (Sandbox Code Playgroud)
它继续返回文本"这应该永远不会返回"而不是在期间超时Thread.Sleep
.
值得注意的是,我也将其扩展Thread.Sleep
到超过Server.ScriptTimeout
110秒的默认值,但它最终仍返回相同的文本而不是超时.
然后,我反而试图设置executionTimeout
在web.config
:
<configuration>
<system.web>
<httpRuntime targetFramework="4.5" executionTimeout="5"/>
...
Run Code Online (Sandbox Code Playgroud)
如果您现在要添加一个断点,TimeoutFilter
您将观察到该ScriptTimeout
值已设置为executionTimeout
值web.config
.唉,这对我来说仍然无效(无论是否debug="false"
).
然后我遇到了这个链接,ScriptTimeout
并executionTimeout
没有使用与你描述的类似的设置.帖子中的第一个回复描述了使用,debug="false"
并且还提到超时将延迟5到15秒.即使使用大Thread.Sleep
值,我仍然没有运气.本文中的第二个回复表明executionTimeout
配置设置是ScriptTimeout
属性的替代(显然是经典ASP中使用的COM接口).此回复表明,如果不使用自己的超时逻辑,则无法设置特定的超时.
此外,我接着发现了以下(最近的)链接,其中第一个回复表明在MVC中关闭了超时.进一步的回复表明,这是因为MVCHandler
(选择将处理的控制器HTTPRequest
)是一个IHttpAsyncHandler
因为它可能正在执行另一个请求(这是使用异步请求的点)它因此在内部切换超时状态off(这是我通过阅读此链接收集的内容).它必须直接asp.net
使用ScriptTimeout
,因为使用似乎是这个答案中可接受的方式.
该链接表明添加以下行将允许它工作(但不在中型信任应用程序中):
System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);
Run Code Online (Sandbox Code Playgroud)
因此,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);
}
Run Code Online (Sandbox Code Playgroud)
并设置web.config
:
<configuration>
<system.web>
<compilation debug="false" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5" executionTimeout="5"/>
...
Run Code Online (Sandbox Code Playgroud)
允许超时工作,但在第一篇文章中提到了轻微的5秒延迟.
注意:使用此方法不允许您ScriptTimeout
在过滤器中设置属性.尝试设置ScriptTimeout
和覆盖设置的值web.config
似乎不起作用.
你在使用调试版本吗?
从ScriptTimeout文档:
http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.scripttimeout(v=vs.110).aspx
如果在Web.config文件中将编译元素的debug属性设置为true,则将忽略ScriptTimeout的值.
此外,由于此值与httpRuntime元素上设置的值相同,我真的不明白这一点,因为您可以在web.config中配置该设置.
编辑:
Dangerous在查找细节方面做得很好,事实上,ScriptTimeout在异步管道中是不受支持的(我认为MVC至少是MVC4,以及WebApi ......即使不使用异步方法)
此连接报告建议的"解决方法":
使用该[AsyncTimeout]
属性,将取消令牌作为参数,然后CanclationToken.ThrowIfCancelationRequested
定期调用,或在异步方法中使用取消令牌.
这是一个例子:
[AsyncTimeout(5000)]
public async Task<ContentResult> Index(CancellationToken ct)
{
await Task.Delay(10 * 1000, ct);
return Content("This should never get returned, mwahahaaa!");
}
Run Code Online (Sandbox Code Playgroud)
这会在5秒后以YSOD引发OperationCanceled异常.这样做的好处是它甚至可以在调试模式下工作;)
归档时间: |
|
查看次数: |
4032 次 |
最近记录: |