0

简而言之,保留在 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
4

2 回答 2

1

您处理此问题的方式与建议的一样——启动一个任务,或所谓的新处理器线程。

所以,你要做的就是分解代码——如果后面的代码是用于 Web 表单的,这甚至可以工作。

因此,第一步是移出“慢”部分,或者我们想要单独运行的部分。

主要问题是启动/启动/想要/希望/实现一个全新的处理器线程?

子调用只能传递一个“参数”,子只能接受一个参数!!!!!!

我注意到在您的情况下,例程需要两个值。

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

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

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

我也非常强烈建议,如果你确实将子放在同一个网页代码后面?您应该/可以将该子标记为共享。如果该例程说试图使用或更新表单上的控件值,这样做将使编译器对您生气并吐出错误。

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

不管以上如何,我们现在可以重新编写我们拥有的代码,如下所示:

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

好的,到目前为止,我们并没有取得太大的成就,但是我们在这里重写以接受 ONE 数组是 KEY。

所以,现在确保上述运行/工作并且都很开心。

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

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

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

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

于 2020-11-03T20:58:55.340 回答
-1

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

Task.Run(() => SendEmail());
于 2020-11-03T08:31:04.493 回答