C#ASP.NET Core Fire and forget

时间:2018-03-16 10:17:49

标签: c# asynchronous asp.net-core

我有一个同步控制器方法

    public IActionResult Action(int num)
    {
        //operations-1

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

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

和DoWork方法

    private bool DoWork(int num)
    {
        //operations

        return true;
    }

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

那时,控制器动作和DoWork()同时执行,但是当我到达

return Ok(a);

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

Task.Factory.StartNew(() => DoWork());
ThreadPool.QueueUserWorkItem(o => DoWork());

但结果是一样的。

我希望DoWork方法返回值,但控制器操作方法不需要该值 - 它将在不同的地方使用,与之无关。

3 个答案:

答案 0 :(得分:0)

任务是high level threads,确保您不会阻止任何上下文。

您要么使用ASP.NET Core 2.0中的RabbitMQIHostedService之类的内容来执行激活并忘记请求完成后启动的任务。

答案 1 :(得分:0)

如果你在项目中使用Db,你可以使用Hangfire它很容易使用后台进程管理器。 https://www.hangfire.io/

您可以非常轻松地使用它,例如BackgroundJob.Enqueue(() => DoWork(num));

答案 2 :(得分:0)

坦率地说,这看起来像X-Y problem。在控制器中执行火灾和忘记呼叫似乎没有多大意义。如果您知道您的操作需要一些时间,那么使用队列和dequeuer webjob可能更好。

话虽如此,您希望实现的目标是:DoWork方法只需async

public IActionResult Action(int num)
{
    //operations-1
    Task.Run(() => DoWork(num)); // async call not awaited

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

public async Task<bool> DoWork(int num)
{
    await Task.Delay(10000);
    var i = 9; // breakpoint will hit after 10s
    return true;
}