当自托管 OWIN 服务器关闭时,如何向 Web API 操作发出取消信号?
How can I signal cancellation to Web API actions when the self-hosted OWIN server shuts down?
我有一个基于 OWIN 的 ASP.NET Web API 托管在 Windows 服务中。我的大多数 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);
}
}
使用 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();
}
}
但我不确定如何让 _cts
成为 CancellationTokens
的源泉,这些 CancellationTokens
可以满足我的行为,同时不会破坏 运行良好的请求取消功能。
我认为 CancellationTokenSource.CreateLinkedTokenSource()
可能会有用,但我不知道如何将各个部分组合在一起。
你能帮忙吗?谢谢!
host.onAppDisposing
当您对从 WebApp.Start
返回的值调用 Dispose
时触发。
默认情况下,GetSomeDataAsync
's 仅与请求断开令牌相关联(例如 owin.CallCancelled
)。通过中间件或其他方式,您可以将其替换为也连接到 host.onAppDisposing
.
的链接 TCS
类似于:
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;
}
});
我有一个基于 OWIN 的 ASP.NET Web API 托管在 Windows 服务中。我的大多数 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);
}
}
使用 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();
}
}
但我不确定如何让 _cts
成为 CancellationTokens
的源泉,这些 CancellationTokens
可以满足我的行为,同时不会破坏 运行良好的请求取消功能。
我认为 CancellationTokenSource.CreateLinkedTokenSource()
可能会有用,但我不知道如何将各个部分组合在一起。
你能帮忙吗?谢谢!
host.onAppDisposing
当您对从 WebApp.Start
返回的值调用 Dispose
时触发。
GetSomeDataAsync
's 仅与请求断开令牌相关联(例如 owin.CallCancelled
)。通过中间件或其他方式,您可以将其替换为也连接到 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;
}
});