【发布时间】:2022-01-22 11:07:46
【问题描述】:
我需要在我的 asp.net webapi(框架 .Net 4.7.2)中调用 Redis(使用 StackExchange.Redis),以便以火灾和忘记的方式删除一个键,我正在做一些压力测试。
当我比较各种方式来获得最大速度时:
- 我已经测试了执行带有 FireAndForget 标志的命令,
- 我还通过 await 测量了一个对 Redis 的简单命令。
- 我现在正在寻找一种方法来收集在 15 毫秒的窗口中收到的命令列表,并通过管道将它们全部执行。
我首先尝试使用 Task.Run Action 来调用 Redis,但我观察到的问题是在压力下,我的 webapi 的内存不断攀升。 内存中充满了 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 会继续在内存中排队后台任务,并尽可能快地一个接一个地执行它们,但比传入的请求要少...
所以我正在寻找一种方法让 只有一个 长期运行的后台线程与 asp.net webapi 一起运行,它可以捕获发送到 Redis 的命令并通过管道执行它们他们。
我正在考虑通过实现 IHostedService 接口来运行后台任务,但在这种情况下,后台任务似乎不会与我当前的 http 请求共享任何状态。因此,实现 IhostedService 对于计划的后台任务会很方便,但在我的情况下不是这样,或者我不知道如何......
【问题讨论】:
-
您不需要 Task.Run 异步任务。直接等待就好了。这不是一劳永逸,但如果你不等待,那么响应就会结束。该 redis 操作应该不会花费大量时间。
-
是的,我没有设置 fireandforget 命令标志。我正在比较各种方法:我已经通过等待这个命令测试了限制,而且速度非常快。但我正在寻找是否有办法将工作推送到后台线程,以便每秒执行更多命令到 redis。
-
that could capture the commands to send to Redis and execute them by pipeling them您不需要处理流水线 - StackExchange.Redis 会在内部为您处理。客户端可能不会单独发送每个单独的消息,而是将它们分组并一次通过网络发送。请参阅Pipelining 文档。
标签: c# asp.net-web-api2 task-parallel-library stackexchange.redis background-task