Asp.net WebAPI:中止(取消)请求

cma*_*art 14 c# asp.net asp.net-mvc asp.net-web-api

对于初学者来说,这是一个讨论,如果你们中的任何人做过WebAPI控制器中的请求取消(可能也适用于MVC).

我的意思是特别是如下情况:客户端(通常是浏览器)启动请求,导航或更一般,因任何原因中止请求.现在,请求在客户端中止,将不再被考虑.但是在服务器端,请求仍在执行,通常可能会做两件特别有趣的事情:

  • 进行(重)DB查询
  • 对另一项服务进行(重)服务呼叫

最后一切都没有(至少当它至少是一个副作用免费读取操作时).

在这种情况下,有人会处理正在进行的查询/服务呼叫的取消吗?

我所知道的是,a CancellationToken可以在API-Controller中传递(即使我无法使其工作,以便在从客户端中止时真正请求取消).这CancellationToken在理论上将需要向下传递到所有的低层处理的数据库和服务呼叫可能取消.

Pau*_*ner 11

虽然在撰写本文时,WebAPI并不直接支持取消,但OWIN API绝对可以.如果您正在使用WebAPI 2.0,那么您将在OWIN之上运行,并且能够使用GetOwinContext()扩展方法通过Microsoft包装器访问上下文.

方便地,使用CancellationToken通过CallCancelled属性暴露的值来传播消除OwinRequest.您可以将所有内容放在一起以获取控制器方法内的令牌:

public async Task Get()
{
    var cancellation = Request.GetOwinContext().Request.CallCancelled;

    await database.FooAsync(cancellation);
}
Run Code Online (Sandbox Code Playgroud)

那很难看.您必须在需要处理取消的每个方法中进行此调用,并且它与WebAPI将为您提供的建议的未来不能很好地协作CancellationToken.相反,如果我们能把它变成一个参数,那会不会更好?

public async Task Get(CancellationToken cancellation)
{
    await database.FooAsync(cancellation);
}
Run Code Online (Sandbox Code Playgroud)

为此,您可以创建一个CancellationToken从OWIN上下文中获取的自定义参数绑定:

public class OwinCancellationTokenBinding : HttpParameterBinding
{
    public OwinCancellationTokenBinding(HttpParameterDescriptor parameter)
        : base(parameter)
    {
    }

    public override Task ExecuteBindingAsync(
        ModelMetadataProvider metadataProvider, 
        HttpActionContext actionContext,
        CancellationToken cancellationToken)
    {
        actionContext.ActionArguments[Descriptor.ParameterName]
            = actionContext.Request.GetOwinContext().Request.CallCancelled;

        return Task.FromResult<object>(null);
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,您可以HttpConfiguration使用其ParameterBindingRules集合注册绑定:

config.ParameterBindingRules.Add(p
    => p.ParameterType == typeof(CancellationToken)
    ? new OwinCancellationTokenBinding (p)
    : null);
Run Code Online (Sandbox Code Playgroud)

此规则匹配任何类型的参数CancellationToken.您可以在此处创建与您希望为此值提供的参数匹配的任何规则.