iis 如何在ASP.NET4中执行长时间运行的任务?

ogsagwnx  于 2023-06-23  发布在  .NET
关注(0)|答案(7)|浏览(145)

我正在使用.NET 4创建一个网站。有很多MSDN文章可以追溯到2003年,关于使用Thread对象和2007, using Asynchronous Pages in .NET 2,但这些都很陈旧。我知道.NET 4为我们带来了Task classsome people vaguely cautioning against its use for this purpose
所以我问你,在2011年左右,在ASP.NET4的IIS下运行后台/异步工作的“首选”方法是什么?直接使用Thread/Task有哪些注意事项?Async=true还流行吗?
编辑:好吧,好吧,从答案中可以清楚地看出,我应该尽我所能提供服务。但是在webapp中做的好处是显著的,特别是更容易部署/重新部署。假设该进程可以安全崩溃,那么,如果我在IIS中执行此操作,最好的方法是什么?

nuypyhwy

nuypyhwy1#

优选地,避免在这样的环境中执行长任务。
通过互操作性将长时间运行的任务委托给稳定的系统服务,使Web应用程序响应,并且只需要直接的用户请求。
Web应用程序从来没有被认为是可靠的系统(现在也不是)--任何使用过浏览器的人都(至少)遇到过超时,这是肯定的;并且这种不便(对于双方而言)不限于这种情况。当然,任何系统都可能崩溃,但是在一个系统上发生这种事件的情况应该是完全例外的。
Windows服务被设计为长时间运行,如果出现问题,您通常需要担心的是您的个人服务。

lbsnaicq

lbsnaicq2#

最好是避免,但如果你不得不这样做,请考虑一下Hanselman在How to run Background Tasks in ASP.NET上的想法。
其中,对于一些快速和简单的东西,我建议你特别看看4.5.2中添加的QueueBackgroundWorkItem
从个人经验来看,任务并没有削减它。QueueBackgroundWorkItem要好得多。

zzoitvuj

zzoitvuj3#

您可以创建一个静态线程池,如http://www.dotnetperls.com/threadpool,线程数有限(例如只有2个)。然后在其中排队任务,但强烈不建议这样做,因为Web服务器不支持此类任务

7d7tgy0s

7d7tgy0s4#

我喜欢的方法与罗伯特·哈维在他的回答中提出的相同。
您仍然可以使用Task Parallel Library,但在IIS之外的单独进程中启动任务(原因是IIS分发的工作线程数量有限,并且施加了其他限制,这些限制可能会使长时间运行的任务不可预测)。

u5i3ibmn

u5i3ibmn5#

这是对“一天一次”场景的描述。
如果你真的想避免创建一个服务,你可以启动一个间隔为1分钟的计时器。每次调用计时器委托时,您都必须运行类似于以下内容(伪代码):

lastInvokeDay = LoadLastInvokeDate();
If (lastInvokeDay < DateTime.Now.Date && timeOfDayToRun == DateTime.Now.Time)
{
  try
  {
    today = DateTime.Now.Date;
    runMyTask();
  }
  catch..
  finally
  {
    lastInvokeDay = today;
    SaveLastInvokeDay(lastInvokeDay);
  }
}

请记住,lastInvokeDay应该持久化在Database或文件中...
现在,如果您想启用任务的立即调用,只需按需调用runMyTask()即可。如果让runMyTask一天不超过一次很重要,可以在其中创建一个同步代码块(使用lock语句),并将lastInvokeDay检查移到内部。
这回答了你的问题吗?

3mpgtkmj

3mpgtkmj6#

我可以建议一个简单的解决方案,它不使用Windows服务,但能够调用一个任务在IIS沙箱之外执行。它也可以很容易地被任何其他语言或它们的混合所采用,在我的例子中是Python
1.在IIS服务器上创建事件日志和源(需要管理权限),从PowerShell控制台执行:

[System.Diagnostics.EventLog]::CreateEventSource('Automations', 'Automations')

如果您没有管理权限,请跳过此步骤。您将回退到使用Windows/应用程序日志
1.创建要对事件执行的任务计划程序任务,例如,ID = 2020,Log = 'Automations'和Source = 'Automations'。在那里,您可以使用所有必要的权限调用任何您喜欢的内容
1.在处理Web请求时,准备发送事件的代码。给你一个Python的例子,但你可以把它应用到你的语言中:

import win32evtlog
app_name = "Automations"
event_id = 2020
event_category = 0
event_type = win32evtlog.EVENTLOG_INFORMATION_TYPE
messages = ['Starting automation']

# Logs event into the custom Automations log if it exists,
# otherwise logs event into Windows/Application log
handle = win32evtlog.OpenEventLog("localhost", app_name)
win32evtlog.ReportEvent(handle, event_type, event_category, event_id, None, messages, None)

1.利润

rdrgkggo

rdrgkggo7#

我强烈推荐https://www.hangfire.io/
在.NET和.NET Core应用程序中执行后台处理的简单方法。不需要Windows服务或单独的进程。
坚持它的“工作”,例如。SQL Server,在我6年多的时间里,我几乎在我开发的每一个企业应用程序中都使用了...从来没有任何问题。
只是工作。

相关问题