首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# ASP.NET核心即发即弃

C# ASP.NET核心即发即弃
EN

Stack Overflow用户
提问于 2018-03-16 18:17:49
回答 4查看 9.9K关注 0票数 3

我有一个同步控制器方法

代码语言:javascript
复制
    public IActionResult Action(int num)
    {
        //operations-1

        Task.Run(() => DoWork(num));

        //operations-2
        int a = num + 123;
        return Ok(a);
    }

和DoWork方法

代码语言:javascript
复制
    private bool DoWork(int num)
    {
        //operations

        return true;
    }

我尝试做的是在从Postman调用端点时在后台运行DoWork方法,但我想在Postman中获得结果,然后调试DoWork方法(从DoWork方法中的断点)-这可能吗?

在那一刻,控制器操作和DoWork()是同时执行的,但是当我到达

代码语言:javascript
复制
return Ok(a);

应用程序等待DoWork,而不是返回值。我也试过了

代码语言:javascript
复制
Task.Factory.StartNew(() => DoWork());
ThreadPool.QueueUserWorkItem(o => DoWork());

但结果是一样的。

我希望DoWork方法返回值,但控制器操作方法不需要返回值-它将在不同的位置使用,而不是与之连接。

EN

回答 4

Stack Overflow用户

发布于 2018-03-16 18:23:19

Tasks是high level threads,它确保你不会阻塞任何上下文。

您可以使用诸如ASP.NET Core2.0中的RabbitMQIHostedService之类的东西来执行在请求完成后触发并忽略的任务。

票数 0
EN

Stack Overflow用户

发布于 2021-08-24 13:21:08

使用后台队列有时有些夸大其词。当您需要访问数据库上下文时,有许多站点向您展示了一种方法。控制器中Task.Run的问题是,衍生的任务不能访问控制器使用的相同上下文,因为它可能(可能会)在该任务访问它之前被处理。您可以通过确保子任务只引用它知道将保持活动状态的依赖项来解决此问题,方法是使用singleton service或更好的数据库上下文,使用IServiceScopeFactory

关键是要创建一个可以处理数据库上下文或存储库的独立依赖项。这可以像平常一样注入到你的控制器中。

代码语言:javascript
复制
    public void Execute(Func<IRepository, Task> databaseWork)
    {
        // Fire off the task, but don't await the result
        Task.Run(async () =>
        {
            // Exceptions must be caught
            try
            {
                using var scope = _serviceScopeFactory.CreateScope();
                var repository = scope.ServiceProvider.GetRequiredService<IRepository>();
                await databaseWork(repository);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        });
    }

然后从你的控制器调用它,比如

代码语言:javascript
复制
        // Delegate the slow task another task on the threadpool
        _fireForgetRepositoryHandler.Execute(async repository =>
        {
            // Will receive its own scoped repository on the executing task
            await repository.DoLOngRunningTaskAsync();;
        });
票数 0
EN

Stack Overflow用户

发布于 2022-01-11 10:10:38

注意:这是建立在Adem Catamak的答案之上的。

可以使用Hangfire,但不需要实际的数据库,因为它可以与memory storage一起使用

代码语言:javascript
复制
services.AddHangfire(opt => opt.UseMemoryStorage());
JobStorage.Current = new MemoryStorage();

虽然它有一些开销,但Hangfire允许管理这些作业,而不是让一些东西异步运行,并需要自定义代码来处理简单的事情,如运行时,未处理的异常,DI支持的自定义代码。

图片来源:Codidact

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

https://stackoverflow.com/questions/49318224

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档