我正在寻找一种可配置的方式在后台线程上运行一些代码,我不太确定“最佳实践”是什么。目前我有以下几点:
Dim sendEmails = Sub()
Dim emailToSend As New SendEmailRequest()
TransferCommonValuesTo(emailToSend, request, sendingUser)
usersToSendEmailTo.ForEach(Sub(u)
TransferValuesTo(emailToSend, u, m_EmailMessageMerger.GetMergedMessage(request.Message, u))
m_EmailSender.Send(emailToSend)
End Sub)
End Sub
If cfg.SendBulkEmailUsingBackgroundThread Then
Dim worker As New Thread(sendEmails)
worker.IsBackground = True
worker.Start()
Else
sendEmails()
End If
这是实现我的要求的好方法吗?
更新
这将从ASP.NET前端调用(尽管其他可能),我使用的是Framework 3.5。
答案 0 :(得分:2)
我倾向于在自己的类中将这种行为抽象为TaskRunner,并且有一个接受Action的Run方法。这会分离线程问题并使您的代码更整洁,您还可以更灵活地实现异步行为,而无需将其嵌入到应用程序的各个类中。
如果您确实在Asp.Net应用程序中运行了异步操作,则需要查看一种机制以使应用程序保持活动状态以防止应用程序回收,例如通过在操作正在运行时轮询站点中的页面来维护活动请求,以便运行时不会认为它处于空闲状态。
答案 1 :(得分:1)
我怀疑大多数人会倾向于使用BackgroundWorker课程。 当然,你也可以在.NET 4.0中使用Task(of T)。
答案 2 :(得分:0)
这几乎总是一个坏主意!例如,考虑IIS中具有默认设置的情况。如果应用程序池空闲(即没有收到任何请求)20分钟,IIS会关闭应用程序池。在这种情况下,如果您的后台作业运行超过20分钟,它将失败。 IIS关闭应用程序池还有其他几个原因。如果有人更改web.config,则应用程序域可以回收,从而导致作业失败。总的来说,它不利于Web应用程序的稳定性。
执行此操作的正确方法是使用Windows服务或其他一些计划组件(可能是数据库服务器中的作业)。 有几种开源选项可供选择。对于例如Quartz.net