首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在asp.net webapi中只有一个线程来触发和忘记任务?

如何在asp.net webapi中只有一个线程来触发和忘记任务?
EN

Stack Overflow用户
提问于 2021-12-20 13:58:17
回答 1查看 275关注 0票数 0

在我的asp.net webapi (框架.Net 4.7.2)中,我需要调用Redis (使用StackExchange.Redis),以便删除火灾中的密钥并忘记,我正在进行一些压力测试。

当我比较不同的方式来获得最大的速度:

  • 我已经用FireAndForget标志测试了执行命令,
  • 我还测量了一个简单的命令到Redis,等待它。
  • 现在,我正在寻找一种方法来收集在15 to窗口中接收到的命令列表,然后通过流水线方式一次执行所有命令。

我第一次尝试用Task.Run动作给Redis打电话,但我观察到的问题是,在压力下,我的webapi的记忆一直在上升。内存中满是带有折叠代码的System.Threading.IThreadPoolWorkItem[]对象:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [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是很方便的,但在我的情况下不是这样,或者我不知道如何实现.

EN

回答 1

Stack Overflow用户

发布于 2021-12-20 16:53:34

基于StackExchange.Redis文档,您可以使用CommandFlags.FireAndForget标志:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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;
}

编辑1:基于注释的另一种解决方案

您可以使用pub/sub方法。像这样的事情应该有效:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MessageBatcher
{
    private readonly IDatabase target;
    private readonly BlockingCollection<Action<IDatabaseAsync>> tasks = new();
    private Task worker;

    public MessageBatcher(IDatabase target) => this.target = target;

    public void AddMessage(Action<IDatabaseAsync> task) => tasks.Add(task);
    
    public IDisposable Start(int batchSize)
    {
        var cancellationTokenSource = new CancellationTokenSource();
        worker = Task.Factory.StartNew(state =>
        {
            var count = 0;
            var tokenSource = (CancellationTokenSource) state;
            var box = new StrongBox<IBatch>(target.CreateBatch());
            tokenSource.Token.Register(b => ((StrongBox<IBatch>)b).Value.Execute(), box);
            foreach (var task in tasks.GetConsumingEnumerable(tokenSource.Token))
            {
                var batch = box.Value;
                task(batch);
                if (++count == batchSize)
                {
                    batch.Execute();
                    box.Value = target.CreateBatch();
                    count = 0;
                }
            }
            
        }, cancellationTokenSource, cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);

        return new Disposer(worker, cancellationTokenSource);
    }

    private class Disposer : IDisposable
    {
        private readonly Task worker;
        private readonly CancellationTokenSource tokenSource;

        public Disposer(Task worker, CancellationTokenSource tokenSource) => (this.worker, this.tokenSource) = (worker, tokenSource);

        public void Dispose()
        {
            tokenSource.Cancel();
            worker.Wait();
            tokenSource.Dispose();
        }
    }
}

用法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private readonly MessageBatcher batcher;

ctor(MessageBatcher  batcher) // ensure that passed `handler` is singleton and already already started
{
    this.batcher= batcher;
}

[HttpPost]
[Route("api/values/testpostfireforget")]
public  ApiResult<int> DeleteFromBasketId([FromBody] int basketId)
{
    var response = new DeleteFromBasketResponse<int>();
    var cpt = Interlocked.Increment(ref counter);

    batcher.AddMessage(db => db.StringSetAsync($"BASKET_TO_DELETE_{cpt}", cpt.ToString(), flags: CommandFlags.FireAndForget));  

    return response;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70428482

复制
相关文章
IntelliJ IDEA Maven 项目的依赖分析
在这个标签页中,我们可以看到我们项目中导入的依赖有哪些冲突,并且这些冲突是怎么冲突的。
HoneyMoose
2023/10/12
2830
IntelliJ IDEA Maven 项目的依赖分析
IntelliJ IDEA 针对 Maven 项目的代码生成
比如说 protobuf,这部分代码不是在 src 目录中的,而是在 target 文件夹中的。
HoneyMoose
2022/01/28
5630
Vue3项目的创建和托管
前面我们在学习Vue的时候都是将Vue的代码直接写在html文件的script中,但实际工作中,我们会使用工具(比如vue-cli)创建完整的项目结构,同时将vue项目托管于nodeJS等JS运行时,实现前端服务的生产化部署。
Python研究所
2022/06/17
7440
Vue3项目的创建和托管
面试加分项-HashMap源码中这些常量设计目的你知道吗
之前周会技术分享,一位同事讲解了HashMap的源码,涉及到一些常量设计的目的,本文将谈谈这些常量为何这样设计,希望大家有所收获。
捡田螺的小男孩
2020/04/15
5510
面试加分项-HashMap源码中这些常量设计目的你知道吗
数据迁移中的几个问题总结
总结一下昨晚在数据迁移前线奋战碰到的一些问题,虽然总体来说是按照预定的计划完成,并且提前完成,但是哪怕一丁点儿的操作都会导致一些严重的影响。 总体来说,需要做的事情就是把核心业务服务器从一个机房迁移到另外一个机房,这个过程中因为环境的重要性和硬件软件的情况,大体分为了下面三个方向的技术方案。 迁移部分核心业务从Solaris到X86平台,同时需要升级数据库版本 迁移x86平台的部分核心业务,这个方向操作相对简单,基本就是主备切换 整合部分X86平台的环境,比如数据库a,b整合后就是一个数据库a
jeanron100
2018/03/21
1.2K0
react-admin+material ui5.0项目的总结
为了更好的进行前后端的设计开发 后端目前用postgrest设计数据库 前端直接使用react-admin和material ui 5.0进行开发 大大增加开发效率
爱学习的前端歌谣
2023/10/18
3570
react-admin+material ui5.0项目的总结
IntelliJ 中配置 Anaconda
在 IntelliJ 中选择 File > Project Structure > Platform Settings > SDKs
HoneyMoose
2020/06/01
6860
IntelliJ 中配置 Anaconda
IntelliJ IDEA 运行项目的时候提示 Command line is too long 错误
这时候你需要调整运行项目的配置,将 Configuration 中的 Shorten Command Line 修改为 JAR 就可以了。
HoneyMoose
2019/10/10
6100
IntelliJ IDEA 运行项目的时候提示 Command line is too long 错误
这时候你需要调整运行项目的配置,将 Configuration 中的 Shorten Command Line 修改为 JAR 就可以了。
HoneyMoose
2019/10/12
1.7K0
IntelliJ IDEA 运行项目的时候提示 Command line is too long 错误
Java中List遍历的几个问题
之前在项目中引入Lambda表达式后,最近就把之前的代码改为Lambda表达式,中间遇到了一个小插曲就是List的在调用Stream的forEach()中使用return 、break、continue关键字的问题;加上最近一直关注的“码农每一题”于是自己回顾一下List的基础温故而知新了;
用户7886150
2020/12/03
1.3K0
详解基于Vue2.0项目的webpack配置文件
Vue提供了一个很好的命令行工具:vue-cli,用来快速构建Vue项目。 现在,我们改造一个由vue-cli创建的simple project,使其提供更强大的功能。
娜姐
2022/05/13
2.1K0
详解基于Vue2.0项目的webpack配置文件
IntelliJ中Spring识别BUG
最近开始学习Spring,在看《Spring实战4th》3.3“处理自动装配的歧义性”那一部分时,书上提到(也从网上看到了类似的用法): 通过在一个类上加注@Component以及@Qualifier(“x”)可以为其配置限定符来标识区分同一个接口下的不同实现类,用以在需要进行@Autowired自动装配的地方使用@Qualifier(“x”)来指定特定的实现类对象bean。
w4ngzhen
2023/10/16
1350
IntelliJ IDEA启动一个普通的java web项目的配置
这是我很久以前刚开始用IntelliJ IDEA时记录的笔记,正好赶上最近离职了,可以有比较多的时间把以前的记录整理一下,可以让刚接触到IntelliJ IDEA的童鞋学习如何在IntelliJ IDEA引入一个单机版的jar形式的小项目。
朱季谦
2019/09/18
2K0
IntelliJ IDEA启动一个普通的java web项目的配置
intellij idea创建第一个动态web项目的步骤方法
2.第二步 1.找到Java Enterprise之后,在Application Sever中找到自己的Tomcat,同时勾选中Web Application
Twcat_tree
2022/11/30
4340
intellij idea创建第一个动态web项目的步骤方法
IntelliJ 中如何配置 Tomcat 调试
在弹出的添加页面中选择添加 Tomcat,你可以选择添加本地的,你也可以选择添加远程的。
HoneyMoose
2023/08/28
3200
IntelliJ 中如何配置 Tomcat 调试
IntelliJ IDEA 中的版本控制介绍(中)
由于 IntelliJ IDEA 支持的版本控制工具非常的多,但咱们真正能够用到的也就两三个而已,因此在本篇博文中,咱们主要介绍 SVN、Git 和 GitHub 的配置方法。 SVN 如果想要在 I
CG国斌
2018/01/26
1K0
IntelliJ IDEA 中配置、使用 SVN
如下图: file -- setting -- version control -- subversion -- 选择 SVN安装路径 -- apply -- OK
微风-- 轻许--
2022/04/13
1.4K0
IntelliJ IDEA 中配置、使用 SVN
IntelliJ IDEA中创建java项目
IntelliJ IDEA支持java、Android、Maven、Gradle、Kotlin等类型的项目,同时Android Studio就是在其基础上二次开发出来的,功能非常强大。 本文以IntelliJ IDEA 2018.2.5版本为例介绍如何创建java项目。 1.依次选择菜单:File->New->Project…,打开New Project界面。 2.在左侧的项目类型里选择:Java,点击Next按钮。 3.在出现的界面中选中“Create project from template”复选框,并选择“Java Hello World”选项,点击Next按钮。(此处可以不选,直接点击Next按钮) 4.在出现的界面中的“Project name”输入框中输入项目的名称,比如:myproject。在“Project location”中可以更改项目的保存路径。 5.点击“Finish”按钮,完成创建。
全栈程序员站长
2022/09/08
5700
在IntelliJ IDEA中配置maven
在IntelliJ IDEA中配置maven 打开-File-Settings  5.新建maven WEB项目 打开-File-New-Project  点击NEXT  点
似水的流年
2018/01/18
1.3K0
在IntelliJ IDEA中配置maven
IntelliJ IDEA中@Autowired注入报错
【解决】 IDEA过于强大,会在运行时扫描所用的所有包,而在扫描的时候IDEA一旦不能明确是哪里有包就会报错,但是在这里我们的配置是没有问题。 所以,找到设置的地方,找到如下图所示的地方,将【Autowiring for Bean Class】的Severity的级别从Erroor改成Warring即可。
foochane
2019/05/23
4.6K0
IntelliJ IDEA中@Autowired注入报错

相似问题

IntelliJ -几个问题

12

没有在IntelliJ IDEA中运行Java9项目的选项

02

如何用Intellij建立WSL2项目的分级?

10

Mercurial下Vaadin 8项目的“.hgignore”文件使用IntelliJ

13

关于编辑栏目的几个问题

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文