单击按钮后无需等待操作完成即可发送电子邮件 ASP.NET

Send Email without waiting for the action to finish execution after Button click ASP.NET

简而言之,留在 HTTP 上下文中,我希望用户在单击订单完成按钮后,不要等待邮件发送后再返回“thak you page”。

我看到 HostingEnvironment.QueueBackgroundWorkItem 可以帮助我解决这个问题,但它总是有被 IIS 回收杀死的风险。

执行此操作的最佳解决方案是什么?

我知道最好是开发一个单独的控制台解决方案,但对于 3/4 的电子邮件来说不值得,或者我可以考虑通过使它们异步来加快速度?

Protected Sub btnConcludiOrdine_Click(sender As Object, e As System.EventArgs) Handles btnConcludiOrdine.Click
    If IsValidOrder(Me._cart, msg) Then
      If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
           'Update quantity in db
           Dim mail As New EmailBLL
           mail.SendOrderNotice(Me._cart, Me._lang) '2 Mails
           mail.SendProductNotice() '2 Mails
      End If
    Else
      Response.Redirect("*Error URL*")
    End If
End Sub

只需在 Task 中推送您的发送邮件逻辑,如果您对结果不感兴趣,请不要等待。 c# 语法

Task.Run(() => SendEmail());

您采用的方法与建议的一样——启动一个任务,或所谓的新处理器线程。

因此,您要做的是分解代码——如果代码隐藏是针对 Web 表单,这甚至有效。

所以,第一步是移出“慢”部分,或者我们想要 运行 分开的部分。

主要问题是start/launch/want/desire/achieve一个全新的处理器线程?

sub call CAN ONLY PASS ONE “parameter” sub can only accept one parameter!!!!!

我注意到你的例程需要两个值。

然而,“一个参数”可以是“多个”值的数组,甚至是一个集合或其他任何东西。在我们的例子中,我们传递了两个值。

所以请记住,您调用的内容不能更新或“使用”表单上控件的值——该表单的实例将超出范围。

但我们当然可以传递您需要的值。这将允许该例程 运行 100% 独立于 Web 表单。

我也强烈建议您是否将子代码放在同一网页代码后面?您 should/can 将该子标记为共享。如果该例程说尝试使用或更新表单上的控件值,那么这样做会让编译器生你的气并吐出错误。

但是,最好将此子放在 Web 表单代码后面的单独标准代码模块中。

尽管如此,我们现在可以 re-write 我们拥有的代码如下:

If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
       
       Dim myInfo(1) as object
       myInfo(0) = me.cart
       myInfo(1) = me_._lng

       Call MyUpdateQ(myInfo) 
  End If
  ' bla bla lba


Shared Sub MyUPdateQ(p() as object)

       'Update quantity in db
       Dim mail As New EmailBLL

       mail.SendOrderNotice(p(0),p(1) 
       mail.SendProductNotice() '2 Mails

End Sub

好的,到目前为止,我们取得的成果不多,但我们re-writing接受一个数组是这里的关键。

所以,现在确保以上runs/works一切顺利。

现在,因为我们将“工作负载”移到了那个例程中,所以现在启动一个线程是一件简单的事情。

现在,我们上面的代码变成了这样:

Protected Sub btnConcludiOrdine_Click(sender As Object, e As System.EventArgs) Handles btnConcludiOrdine.Click

   If IsValidOrder(Me._cart, msg) Then
      If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
         Dim myInfo(1) as object
         myInfo(0) = me.cart
         myInfo(1) = me_._lng

         Dim MyThread As New Thread(New ParameterizedThreadStart(AddressOf MyUpdateQ))

         MyThread.Start(myInfo)
      End If
   Else
      Response.Redirect("*Error URL*")
   End If
End Sub

Shared Sub MyUPdateQ(p() as object)

       'Update quantity in db
       Dim mail As New EmailBLL

       mail.SendOrderNotice(p(0),p(1) 
       mail.SendProductNotice() '2 Mails

End Sub

就是这样。现在,当您单击按钮时,它将等待零时间,因为长 运行ning 例程现在将 运行 100% 作为一个单独的线程。这也意味着当用户单击按钮时 - 页面将立即响应并且 post 返回给用户将完成。因此,如果该线程需要 6 秒,甚至 25 秒,用户将不会注意到此延迟。