请求完成后处理

时间:2016-07-10 15:45:33

标签: asp.net-web-api asp.net-core

我有一个API端点需要尽快返回给调用者。它目前返回不到1毫秒。但是,如果我将一些内容记录到数据库中,现在需要接近10毫秒。

如何完成请求,然后在请求完成后进行某种处理?我尝试使用Response.Body.Flush(),但这并没有完成请求,它仍然需要整整10毫秒。看起来它正在发送/刷新有效负载,但在动作方法完成之前,请求仍然没有完成。

是否可以在中间件中进行日志记录?

编辑:

我找到的一个解决方法是使用FluentScheduler,如下所示:

JobManager.Initialize(new Registry());
JobManager.Start();
在Host.cun()之前的Program.cs中

然后从这样的动作安排一个即时任务:

JobManager.AddJob(() =>
{
    // do something...
}, (s) => s.ToRunOnceIn(1).Seconds());

4 个答案:

答案 0 :(得分:2)

你需要以某种方式开始一个不同的线程。放在管道前面的中间件将使您有机会在请求完成之前完成工作。如果你从那里旋转一个线程,那么它可能会起作用。

你可能想要使用某种producer-consumer pattern,这样你就不会杀掉你的服务器。否则,如果每个请求都启动了一个立即生效的线程,并且您同时有多个请求,那么最终可能会耗尽资源。生产者 - 消费者会帮助你限制这项工作。

如果您不赶时间,我可以等待一周左右,当我为ASP.NET提供文件记录器时,您会在那里看到类似的实现。

答案 1 :(得分:1)

登录中间件不会对您有所帮助,因为您仍然在请求管道中,并且您可能有也可能没有必要的信息来记录您需要做的事情。

您可以异步登录,这可能会在没有重大架构更改的情况下为您带来最大的改进:Async Programming : Introduction to Async/Await on ASP.NET

如果这不起作用,您可以执行多线程的操作。这变得更复杂,但它仍然可行:Multithreading in C# .NET 4.5 (Part 1)

答案 2 :(得分:0)

异步是解决此问题的正确方法。在您的请求期间(无论何时),启动对数据库的异步连接/查询。只是不要等它完成。

答案 3 :(得分:0)

这只是一个想法,所以如果我离开的话,请不要投票。你能用HttpResponse.RegisterForDispose()吗?例如:

public class JobToRunAfterRequestIsComplete : IDisposable {
    public void Dispose()
    {
        // Do your post-processing here.
    } 
}

public class YourController {
    public void YourAction() {
        // Do your normal processing here
        ...
        // Register your post processing here
        this.Response.RegisterForDispose(new JobToRunAfterRequestIsComplete ());
    }
}