簡體   English   中英

如何在 asp.net webapi 中只有一個線程用於觸發並忘記任務?

[英]How to have only one thread for fire and forget task in asp.net webapi?

我需要在我的 asp.net webapi(framework.Net 4.7.2)中調用 Redis(使用 StackExchange.Redis),以便以火災和忘記的方式刪除一個鍵,我正在做一些壓力測試。

當我比較獲得最大速度的各種方式時:

  • 我已經用 FireAndForget 標志測試了執行命令,
  • 我還通過 await 測量了一個對 Redis 的簡單命令。
  • 我現在正在尋找一種方法來收集在 15ms 的 window 中收到的命令列表,並通過管道將它們全部執行在一個 go 中。

我首先嘗試使用 Task.Run Action 調用 Redis 但我觀察到的問題是在壓力下,我的 webapi 的 memory 不斷攀升。 memory 充滿了System.Threading.IThreadPoolWorkItem [] 對象,代碼如下:

    [HttpPost]
    [Route("api/values/testpostfireforget")]
    public  ApiResult<int> DeleteFromBasketId([FromBody] int basketId)
    {

        var response = new DeleteFromBasketResponse<int>();

        var cpt = Interlocked.Increment(ref counter);

            Task.Run(async () => {
                await db.StringSetAsync($"BASKET_TO_DELETE_{cpt}",cpt.ToString())
                         .ConfigureAwait(false); 
            });  
           return response;
     }

所以我認為在壓力下,我的 api 繼續在 memory 中排隊后台任務,並盡可能快地一個接一個地執行它們,但比進來的請求少......

所以我正在尋找一種方法,讓只有一個長壽命的后台線程與 asp.net webapi 一起運行,它可以捕獲發送到 Redis 的命令並通過管道傳輸它們來執行它們

我正在考慮通過實現 IHostedService 接口來運行后台任務,但在這種情況下,后台任務似乎不會與我當前的 http 請求共享任何 state。 因此,實施 IhostedService 對於計划的后台任務會很方便,但在我的情況下不是,或者我不知道如何......

根據StackExchange.Redis 文檔,您可以使用CommandFlags.FireAndForget標志:

[HttpPost]
[Route("api/values/testpostfireforget")]
public  ApiResult<int> DeleteFromBasketId([FromBody] int basketId)
{

    var response = new DeleteFromBasketResponse<int>();
    var cpt = Interlocked.Increment(ref counter);

    db.StringSet($"BASKET_TO_DELETE_{cpt}", cpt.ToString(), flags: CommandFlags.FireAndForget);  

    return response;
}

暫無
暫無

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

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