我想为我的AsyncController设置一个可配置的超时值。我知道我们可以使用[AsyncTimeout(5000)]
属性修饰方法,我们也可以将该值与const变量一起使用。我想使用静态变量,以便我可以使用更可配置的方式在编译后设置超时。
阅读此AsyncManager似乎有一个名为timeout的属性可以设置。
这是我尝试过的。
[HttpPost]
public void DoWorkAsync(MyQuery query)
{
AsyncManager.Timeout = TestTimeout; //TestTimeout is a static int set to 120000
AsyncManager.OutstandingOperations.Increment();
(do work)...
}
似乎没有使用AsyncManager.Timeout值,而是在默认的45秒后抛出TimeoutException。
有没有办法在编译时设置此超时值?
答案 0 :(得分:4)
您可以像这样
创建从AsyncTimeoutAttribute
派生的类
public class CustomAsyncTimeoutAttribute : AsyncTimeoutAttribute
{
public CustomAsyncTimeoutAttribute() : base(Params.TimeOut)
{}
}
其中Params.Timeout
包含您的静态超时变量。
或者您可以尝试此操作(只需复制/粘贴基本AsyncTimeout
功能):
public class CustomAsyncTimeoutAttribute : AsyncTimeoutAttribute
{
public CustomAsyncTimeoutAttribute() : base(0)
{}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException("filterContext");
var managerContainer = filterContext.Controller as IAsyncManagerContainer;
if (managerContainer == null)
throw new InvalidOperationException("The operation has timed out.");
managerContainer.AsyncManager.Timeout = //There you can get your timeout parameter from resourse (i.e. config file, database, etc);
base.OnActionExecuting(filterContext);
}
}
此外,您应该使用async
关键字标记您的操作方法,您的方法应该返回Task
或Task<T>
,方法的最后一个参数应为CancellationToken
,否则AsyncTimeout
无效。
例如:
[CustomAsyncTimeoutAttribute]
public async Task PerformAction(/*Some parameters*/, CancellationToken token)
答案 1 :(得分:0)
您真的不需要从AsyncTimeoutAttribute继承。只需创建自己的CustomAsyncTimeoutAttribute并直接从ActionFilterAttribute继承它。否则base.OnActionExecuting(filterContext)将覆盖你的,你肯定会有TimeoutException,因为你在基础构造函数中发送0。
以下是您实现目标的方法。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomAsyncTimeoutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException(nameof(filterContext));
}
var managerContainer = filterContext.Controller as IAsyncManagerContainer;
if (managerContainer == null)
{
throw new InvalidOperationException("CustomAsyncTimeout Action Filter failed");
}
var duration = GetYouDurationAsYouWish();
if (duration < 0)
{
throw new ArgumentOutOfRangeException(nameof(duration));
}
managerContainer.AsyncManager.Timeout = duration;
base.OnActionExecuting(filterContext);
}
}