C# 如何创建可配置的异步超时

C# 如何创建可配置的异步超时,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我想为我的AsyncController设置一个可配置的超时值。我知道我们可以用[AsyncTimeout(5000)]属性来修饰一个方法,并且我们还可以将该值与常量变量一起使用。我想使用一个静态变量,这样我可以有一个更可配置的方式来设置编译后的超时 读到这里,似乎有一个叫做timeout的属性可以设置 这是我试过的 [HttpPost] public void DoWorkAsync(MyQuery query) { AsyncManager.Timeout =

我想为我的AsyncController设置一个可配置的超时值。我知道我们可以用
[AsyncTimeout(5000)]
属性来修饰一个方法,并且我们还可以将该值与常量变量一起使用。我想使用一个静态变量,这样我可以有一个更可配置的方式来设置编译后的超时

读到这里,似乎有一个叫做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


有没有办法在编译时设置此超时值?

您可以像这样创建从
AsyncTimeoutAttribute
派生的类

public class CustomAsyncTimeoutAttribute : AsyncTimeoutAttribute
{
    public CustomAsyncTimeoutAttribute() : base(Params.TimeOut)
    {}       
}
其中
Params.Timeout
包含静态超时变量

或者您可以尝试以下操作(只需复制/粘贴基本
AsyncTimeout
功能):

此外,您应该使用
async
keywork标记您的操作方法,您的方法应该返回
Task
Task
,方法的最后一个参数应该是
CancellationToken
,否则
AsyncTimeout
不起作用

例如:

[CustomAsyncTimeoutAttribute]
public async Task PerformAction(/*Some parameters*/, CancellationToken token)

您实际上不需要从AsyncTimeoutAttribute继承。只需创建自己的CustomAsyncTimeoutAttribute并直接从ActionFilterAttribute继承它。否则base.OnActionExecuting(filterContext)将覆盖您的,并且您肯定会有TimeoutException,因为您在基本构造函数中发送了0

下面是你如何实现它的

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
公共类CustomAsyncTimeoutAttribute:ActionFilterAttribute
{
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
如果(filterContext==null)
{
抛出新ArgumentNullException(nameof(filterContext));
}
var managerContainer=filterContext.Controller作为IAsyncManager容器;
if(managerContainer==null)
{
抛出新的InvalidOperationException(“CustomAsyncTimeout操作筛选器失败”);
}
var duration=GetYouDurationAsYouWish();
如果(持续时间<0)
{
抛出新ArgumentOutOfRangeException(nameof(duration));
}
managerContainer.AsyncManager.Timeout=持续时间;
base.OnActionExecuting(filterContext);
}
}

我尝试了第一个建议,似乎效果很好。谢谢第二种解决方案对我不起作用;参数应该来自后端(CMS)。
[CustomAsyncTimeoutAttribute]
public async Task PerformAction(/*Some parameters*/, CancellationToken token)