Asp.net 在响应之后执行数据库写入

Asp.net 在响应之后执行数据库写入,asp.net,Asp.net,我有一个web服务,它接收用户的请求并返回一些json。我需要将json字符串保存在数据库中,以便在返回响应之前进行写查询 有没有一种方法可以在响应离开web服务后,先发送响应,然后执行写查询 谢谢。您应该看看如何使用MSMQ、ActiveMQ或RabbitMQ等消息队列来实现这一点。当您收到请求时,您将把相关数据放入队列,并将响应发送给客户端。在队列的另一端,您将有一些进程从队列中读取数据并将数据插入数据库。您应该考虑使用消息队列(如MSMQ、ActiveMQ或RabbitMQ)来完成此操作。

我有一个web服务,它接收用户的请求并返回一些json。我需要将json字符串保存在数据库中,以便在返回响应之前进行写查询

有没有一种方法可以在响应离开web服务后,先发送响应,然后执行写查询


谢谢。

您应该看看如何使用MSMQ、ActiveMQ或RabbitMQ等消息队列来实现这一点。当您收到请求时,您将把相关数据放入队列,并将响应发送给客户端。在队列的另一端,您将有一些进程从队列中读取数据并将数据插入数据库。

您应该考虑使用消息队列(如MSMQ、ActiveMQ或RabbitMQ)来完成此操作。当您收到请求时,您将把相关数据放入队列,并将响应发送给客户端。在队列的另一端,您将有一些进程从队列中读取数据并将数据插入到数据库中。

这里有两个不同的选项-尽管它们都有折衷,但这将是非常深奥的。您没有提到为什么要这样做,所以我只是猜测性能。如果是这样的话,我认为你找错了方向——一个简单的写操作几乎肯定不是你的性能问题

所以,在我的脑海里:

排队,将是一个很好的方法。这可以在卸载写操作时获得事务的类似语义。不过,您仍然需要写入队列,这可能与写入数据库的开销大致相同。 您可以使用ThreadPool或System.Threading.thread生成一个新线程——关于在ASP.NET中哪个线程更适合处理写操作,存在一些争论。这通常可以工作,但您可能会遇到未处理的异常、应用程序域重新启动等问题。 您可以将JSON数据存储到静态或应用程序变量中,然后使用计时器定期将它们写入数据库。这将是多线程代码,因此需要同步对集合的读/写操作。 与3类似,将JSON数据存储到缓存中,并使用无效回调写入数据库。 存储在某处的内存、磁盘、平面数据库表等、以后的进程ASP.NET、计划任务、Windows服务、Sql代理等都有很多变化。。 @frenchie说:响应开始于从db读取json字符串,结束于写回。换句话说,如果用户发送请求,那么将要读取的json字符串必须是前一个响应中写入的字符串

这使事情变得复杂,因为异步工作的固有特性是不知道什么时候做了什么。如果需要在处理下一个请求之前将异步部分写回DB,则必须执行等待以确保它实际完成。为了做到这一点,您需要在客户机上保持服务器端的状态——虽然就服务而言,这并不是一种最佳实践,但听起来您已经在使用这些JSON请求/响应对来实现这一点了


考虑到复杂性,我会确保您已经完成了分析,并确定这确实是一个性能问题。

这里有两个不同的选项-尽管它们都有折衷,但这将是相当深奥的。您没有提到为什么要这样做,所以我只是猜测性能。如果是这样的话,我认为你找错了方向——一个简单的写操作几乎肯定不是你的性能问题

所以,在我的脑海里:

排队,将是一个很好的方法。这可以在卸载写操作时获得事务的类似语义。不过,您仍然需要写入队列,这可能与写入数据库的开销大致相同。 您可以使用ThreadPool或System.Threading.thread生成一个新线程——关于在ASP.NET中哪个线程更适合处理写操作,存在一些争论。这通常可以工作,但您可能会遇到未处理的异常、应用程序域重新启动等问题。 您可以将JSON数据存储到静态或应用程序变量中,然后使用计时器定期将它们写入数据库。这将是多线程代码,因此需要同步对集合的读/写操作。 与3类似,将JSON数据存储到缓存中,并使用无效回调写入数据库。 存储在某处的内存、磁盘、平面数据库表等、以后的进程ASP.NET、计划任务、Windows服务、Sql代理等都有很多变化。。 @frenchie说:响应开始于从db读取json字符串,结束于写回。换句话说,如果用户发送请求,那么将要读取的json字符串必须是前一个响应中写入的字符串

这使事情变得复杂,因为异步工作的固有特性是不知道什么时候做了什么。如果您需要在处理下一个请求之前将异步部分写回DB,那么您必须执行一个wait to make 当然,它确实完成了。为了做到这一点,您需要在客户机上保持服务器端的状态——虽然就服务而言,这并不是一种最佳实践,但听起来您已经在使用这些JSON请求/响应对来实现这一点了


考虑到这些复杂性,我会确保您已经完成了分析,并确定这确实是一个性能问题。

这缺少了请求/响应的要点。除非您想使用服务总线之类的异步命令,但这是发布/订阅,而不是请求/响应。请求/响应的要点是在收到请求之后和发送响应之前在服务器上执行工作。即使工作正在向服务总线发送异步消息。

这也缺少请求/响应点。除非您想使用服务总线之类的异步命令,但这是发布/订阅,而不是请求/响应。请求/响应的要点是在收到请求之后和发送响应之前在服务器上执行工作。即使工作正在向服务总线发送异步消息。

您也可以安排查询工作,如

ThreadPool.QueueUserWorkItem(state => 
      this.AsynchronousExecuteReference());

 // and run
 static void AsynchronousExecuteReference()
 {
    // run here your sql update
 }
另一个例子是在类中使用线程,您可以向它传递参数

public class RunThreadProcess
{
    // Some parametres
    public int cProductID;

    // my thread
    private Thread t = null;

    // start it
    public Thread Start()
    {
        t = new Thread(new ThreadStart(this.work));
        t.IsBackground = true;
        t.SetApartmentState(ApartmentState.MTA);
        t.Start();

        return t;
    }

    // actually work
    private void work()
    {
        // do thread work
        all parametres are available here
    }
}
下面是我如何运行它的

  var OneAction = new RunThreadProcess();
    OneAction.cProductID = 100;
    OneAction.Start();

不要担心内存,CG知道这个过程会一直使用到线程结束,所以我必须检查它,CG不会删除它,并等待线程结束。

您可以像这样安排查询工作

ThreadPool.QueueUserWorkItem(state => 
      this.AsynchronousExecuteReference());

 // and run
 static void AsynchronousExecuteReference()
 {
    // run here your sql update
 }
另一个例子是在类中使用线程,您可以向它传递参数

public class RunThreadProcess
{
    // Some parametres
    public int cProductID;

    // my thread
    private Thread t = null;

    // start it
    public Thread Start()
    {
        t = new Thread(new ThreadStart(this.work));
        t.IsBackground = true;
        t.SetApartmentState(ApartmentState.MTA);
        t.Start();

        return t;
    }

    // actually work
    private void work()
    {
        // do thread work
        all parametres are available here
    }
}
下面是我如何运行它的

  var OneAction = new RunThreadProcess();
    OneAction.cProductID = 100;
    OneAction.Start();

不要担心内存问题,CG知道这个过程会一直使用到线程结束,所以我必须检查它,CG不会删除它,并等待线程结束。

您可以尝试将web服务URL移动到一个ASPX页面,在那里生命周期开始发挥作用


在“代码隐藏”中,调用在Page_Load或Page_Prerender中执行主要工作的例程,或者在发送响应之前的适当时间,然后在Page_Unload事件中执行DB工作,该事件在发送响应后发生

您可以尝试将web服务URL移动到一个ASPX页面,在该页面上,生命周期将发挥作用


在“代码隐藏”中,调用在Page_Load或Page_Prerender中执行主要工作的例程,或者在发送响应之前的适当时间,然后在Page_Unload事件中执行DB工作,该事件在发送响应后发生

你能进一步解释/澄清一下吗。我认为你可能混淆了术语,造成了混乱。从客户机发送请求并由服务器接收。请求由服务器处理。服务器发送响应,客户端接收响应。好的,更新了语义。在响应离开后仍希望写入数据库;这可能吗?你能解释/澄清更多关于这一点吗。我认为你可能混淆了术语,造成了混乱。从客户机发送请求并由服务器接收。请求由服务器处理。服务器发送响应,客户端接收响应。好的,更新了语义。在响应离开后仍希望写入数据库;这可能吗?嗨,下一个请求也需要我正在写入数据库的json字符串;请求从读取json字符串开始。另外,谢谢你的代码。我应该把线程池放在哪里。。。在响应离开后,它是如何执行的?@frenchie这是在查询池上发送这个线程,当它的时间到了执行的时候,如果我记得很清楚的话,这不是很安全,我将再举一些传递参数的例子。为了充分利用I/O完成端口,您应该在数据客户机类上使用异步方法。好的,谢谢您的详细回答;我要用它!回答得很好。@frenchie我在这里使用这个代码/类,几年前,它的工作非常完美,我的代码没有内存或其他问题,当然,如果需要添加互斥锁进行同步,则除外。在我的页面中,我打开2或3个线程并并行工作,在页面结束后,我还运行类似的1-2工作;请求从读取json字符串开始。另外,谢谢你的代码。我应该把线程池放在哪里。。。在响应离开后,它是如何执行的?@frenchie这是在查询池上发送这个线程,当它的时间到了执行的时候,如果我记得很清楚的话,这不是很安全,我将再举一些传递参数的例子。为了充分利用I/O完成端口,您应该在数据客户机类上使用异步方法。好的,谢谢您的详细回答;我要用它!回答得很好。@frenchie我在这里使用这个代码/类,几年前,它的工作非常完美,我的代码没有内存或其他问题,当然,如果需要添加互斥锁进行同步,则除外。在我的页面中,我打开2或3个线程并进行工作
并行和页面结束后,我也运行类似的1-2工程。谢谢你的回答。我应该补充一点,响应开始于从db读取json字符串,结束于写回。换句话说,如果用户发送请求,那么将要读取的json字符串必须是前一个响应中写入的字符串。这会改变什么吗?此外,字符串的大小约为4K;考虑到它的尺寸,我应该不担心吗?谢谢你的回答。我应该补充一点,响应开始于从db读取json字符串,结束于写回。换句话说,如果用户发送请求,那么将要读取的json字符串必须是前一个响应中写入的字符串。这会改变什么吗?此外,字符串的大小约为4K;考虑到它的尺寸,我应该不担心吗?嗨,谢谢你的建议。有件重要的事我应该提一下。响应从读取json字符串开始。所以写操作必须发生,这样当用户发送请求时,我们就可以读取最新的json字符串。当请求传入时,如果最新的json字符串在队列中而不是数据库中,会发生什么情况?这些排队服务可以处理吗?您希望写入是异步的,但您的情况需要它是同步的。我觉得你把事情弄得太复杂了,没有什么实际的好处。只需同步写入数据库,然后就可以使用它了。为什么你想跳过所有这些障碍,只是为了避免向数据库中写入一个字符串?嗨,谢谢你的想法。有件重要的事我应该提一下。响应从读取json字符串开始。所以写操作必须发生,这样当用户发送请求时,我们就可以读取最新的json字符串。当请求传入时,如果最新的json字符串在队列中而不是数据库中,会发生什么情况?这些排队服务可以处理吗?您希望写入是异步的,但您的情况需要它是同步的。我觉得你把事情弄得太复杂了,没有什么实际的好处。只需同步写入数据库,然后就可以使用它了。为什么要跳过所有这些障碍来避免向数据库写入一个字符串?