Dav*_*bin 4 c# asp.net owin asp.net-web-api2
我有一个在Windows服务中托管的基于OWIN的ASP.NET Web API.我的大多数ApiController操作都是异步的,并接受CancellationToken参数:
[Route("data/{id}")]
public async Task<IHttpActionResult> GetSomeDataAsync(int id, CancellationToken token)
{
try
{
using (var _dataSource = ...)
{
return Ok(await _dataSource.GetDataAsync(id, token));
}
}
catch (OperationCanceledException ex)
{
return StatusCode(HttpStatusCode.NoContent);
}
}
Run Code Online (Sandbox Code Playgroud)
使用Web API的内置请求取消功能,如果客户端取消请求,token则发出信号并_dataSource适当地处理它并抛出OperationCanceledException.
到目前为止,太棒了.
但是当我的主机进程终止时(即Windows服务停止),token没有发出信号,并且取消和纾困过程不优雅.
我知道OWIN环境字典的host.onAppDisposing属性,我已经挖掘了Microsoft.Owin [.*]和Microsoft.AspNet.WebApi.*包的源代码,试图弄清楚其中GetSomeDataAsync的token参数是什么来自,但我不知道如何将各个部分连接在一起.
我想做点什么
class WebServiceInAWindowsService : ServiceBase
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
...
protected override void OnStop()
{
_cts.Cancel();
}
}
Run Code Online (Sandbox Code Playgroud)
但我不确定如何_cts成为CancellationTokens我的行动的源头,同时不打破运行良好的请求取消功能.
我认为这CancellationTokenSource.CreateLinkedTokenSource()可能有用,但我没有看到如何将各个部分组合在一起.
你能帮我吗?谢谢!
host.onAppDisposing当你调用Dispose返回的值时触发WebApp.Start.
GetSomeDataAsync默认情况下,它仅与请求断开连接令牌相关联(例如owin.CallCancelled).通过中间件或其他方式,您可以将其替换为也连接到的链接TCS host.onAppDisposing.
就像是:
app.Use(async (env, next) =>
{
var reqAbt = env.Get<CancellationToken>("owin.CallCancelled");
var appAbt = env.Get<CancellationToken>("host.onAppDisposing");
using (linked = CancellationTokenSource.CreateLinkedTokenSource(reqAbt, appAbt))
{
env["owin.CallCancelled"] = linked.Token;
await next();
env["owin.CallCancelled"] = reqAbt;
}
});
Run Code Online (Sandbox Code Playgroud)