Ответ 1
В то время, когда WebAPI не поддерживает отмену, API OWIN абсолютно не работает. Если вы используете WebAPI 2.0, вы будете работать поверх OWIN и сможете получить доступ к контексту с помощью оболочек Microsoft, используя GetOwinContext()
.
Удобно, чтобы аннулирование распространялось с использованием значения CancellationToken
, выставленного с помощью свойства CallCancelled
объекта OwinRequest
. Вы можете собрать все это, чтобы получить маркер внутри метода контроллера:
public async Task Get()
{
var cancellation = Request.GetOwinContext().Request.CallCancelled;
await database.FooAsync(cancellation);
}
Это довольно уродливо. Вы должны будете сделать этот вызов в каждом методе, который должен обрабатывать отмену, и это не очень хорошо работает с предлагаемым будущим, где WebAPI предоставит вам этот CancellationToken
. Вместо этого было бы лучше, если бы мы могли сделать это в параметре?
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
. Здесь вы можете создать любое правило, которое соответствует параметрам, для которых вы хотите получить это значение.