首先,如果你们中的任何人做过WebAPI控制器中的请求取消(可能也适用于MVC),这是一个讨论。
我的意思是特别是如下情况: 客户端(通常是浏览器)启动请求,导航或更一般,因任何原因中止请求。现在,请求在客户端中止,将不再被考虑。但是在服务器端,请求仍然在执行,通常可能会做两件特别有趣的事情:
最后一切都没有(至少当它至少是一个副作用的免费阅读操作时)。
在这种情况下,有人会处理正在进行的查询/服务调用的取消吗?
我所知道的是CancellationToken
可以在API控制器中传递(即使我无法使其工作,以便在从客户端中止时真正请求取消)。
理论上,这个CancellationToken
需要传递给所有较低层,以处理数据库和服务调用的可能取消。
答案 0 :(得分:11)
虽然在撰写本文时,WebAPI并不直接支持取消,但OWIN API绝对可以。如果您正在使用WebAPI 2.0,那么您将在OWIN之上运行,并且能够使用GetOwinContext()
扩展方法通过Microsoft包装器访问上下文。
方便地,使用CancellationToken
通过OwinRequest
public async Task Get()
{
var cancellation = Request.GetOwinContext().Request.CallCancelled;
await database.FooAsync(cancellation);
}
属性公开的值传播取消。您可以将所有这些放在控制器方法中以获取令牌:
CancellationToken
但这很丑陋。您必须在需要处理取消的每个方法中进行此调用,并且它与WebAPI将为您提供此public async Task Get(CancellationToken cancellation)
{
await database.FooAsync(cancellation);
}
的建议的未来不能很好地协作。相反,如果我们能把它变成一个参数,会不会更好?
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);
}
}
:
HttpConfiguration
要使用此功能,您可以使用ParameterBindingRules
集合向config.ParameterBindingRules.Add(p
=> p.ParameterType == typeof(CancellationToken)
? new OwinCancellationTokenBinding (p)
: null);
注册绑定:
CancellationToken
此规则匹配printf("EUR%.2d = USD%.2d" euro, dollar);
类型的任何参数。您可以在此处创建与您希望此值提供的参数匹配的任何规则。