簡體   English   中英

當自托管OWIN服務器關閉時,如何向Web API操作發出取消信號?

[英]How can I signal cancellation to Web API actions when the self-hosted OWIN server shuts down?

我有一個在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);
    }
}

使用Web API的內置請求取消功能,如果客戶端取消請求,則會發出token信號並且_dataSource會相應地處理它並拋出OperationCanceledException

到目前為止,太棒了。

但是當我的主機進程終止時 (即Windows服務停止),不會發出token信號,並且取消和紓困過程不是優雅的。

我知道OWIN環境字典的host.onAppDisposing屬性,我已經挖掘了Microsoft.Owin [。*]Microsoft.AspNet.WebApi。*包的源代碼,試圖弄清楚GetSomeDataAsynctoken在哪里爭論來自,但我不知道如何將各個部分連接在一起。

我想做點什么

class WebServiceInAWindowsService : ServiceBase
{
    private readonly CancellationTokenSource _cts = new CancellationTokenSource();
    ...
    protected override void OnStop()
    {
        _cts.Cancel();
    }
}

但是我不確定如何讓_cts成為CancellationTokens行動的源頭, 同時不會破壞運行良好的請求取消功能。

我認為CancellationTokenSource.CreateLinkedTokenSource()可能會有用,但我沒有看到如何將各個部分組合在一起。

你能幫我嗎? 謝謝!

host.onAppDisposing當你調用被觸發Dispose從返回的值WebApp.Start

https://github.com/aspnet/AspNetKatana/blob/9f6e09af6bf203744feb5347121fe25f6eec06d8/src/Microsoft.Owin.Hosting/Engine/HostingEngine.cs#L302-L308

https://github.com/aspnet/AspNetKatana/blob/9f6e09af6bf203744feb5347121fe25f6eec06d8/src/Microsoft.Owin.Hosting/Engine/HostingEngine.cs#L112

GetSomeDataAsync的僅與通過默認值(例如,請求斷開令牌相關聯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;
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM