13

我正在使用 .NET 4 构建一个网站。从2003 年开始有很多 MSDN 文章,关于使用 Thread 对象2007 年,在 .NET 2 中使用异步页面,但这一切都非常陈旧。我知道 .NET 4 为我们带来了Task 类有些人含糊地警告不要将其用于此目的

所以我问你,大约 2011 年在 ASP.NET 4 的 IIS 下运行后台/异步工作的“首选”方法是什么?直接使用线程/任务有什么注意事项?Async=true 还在流行吗?

编辑:好的,好的,从答案中可以清楚地看出,如果可以的话,我应该提供服务。但是在 webapp 中执行它的优势是显着的,尤其是更容易部署/重新部署。假设该过程是安全崩溃的,那么,如果我要在 IIS 中执行它,最好的方法是什么?

4

6 回答 6

18

最好避免在这样的环境中执行长时间的任务。

通过互操作性将长时间运行的任务委托给稳定的系统服务,使 Web 应用程序具有响应性,并且只需要直接用户请求。

Web 应用程序从来没有(现在仍然不是)被认为是可靠的系统——任何曾经使用过浏览器的人都遇到过(至少)超时,这是肯定的;并且这种不便(对双方而言)不仅限于这种情况。当然,任何系统都可能崩溃,但在构建为持久的系统上发生此类事件的情况应该是完全例外的。

Windows 服务的设计目的是长期运行,如果出现问题,您通常需要担心的不仅仅是您的单个服务。

于 2011-04-05T13:58:10.087 回答
2

最好避免,但如果您被迫这样做,请考虑 Hanselman 在How to run Background Tasks in ASP.NET 中的想法。

其中,为了方便快捷,我建议您特别查看 4.5.2 中添加的QueueBackgroundWorkItem

从个人经验来看,Task 并没有削减它。QueueBackgroundWorkItem 要好得多。

于 2015-11-12T23:55:59.443 回答
0

我首选的方法与罗伯特哈维在他的回答中提出的方法相同。

您仍然可以使用Task Parallel Library,但在 IIS 之外的单独进程中启动任务(原因是 IIS 有有限数量的工作线程要分发并施加其他限制,这些限制可能使长时间运行的任务无法预测)。

于 2011-04-05T13:59:01.697 回答
0

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

于 2011-04-05T14:02:27.790 回答
0

这是对“一天一次”场景的描述。

如果你真的想避免创建服务,你可以启动一个以 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 应该保存在数据库或文件中......

现在,如果您想启用任务的立即调用,您可以简单地runMyTask()按需调用。如果让 runMyTask 每天发生一次以上对您很重要,您可以在其中创建一个同步代码块(使用lock语句)并将lastInvokeDay检查移到里面。

这回答了你的问题了吗?

于 2013-07-02T08:13:59.847 回答
0

我可以建议一个简单的解决方案,它不使用 Windows 服务,但能够调用要在 IIS 沙箱之外执行的任务。它也可以很容易地被任何其他语言或它们的混合采用,在我的例子中是 Python

  1. 在 IIS 服务器上创建事件日志和源(需要管理权限),从 PowerShell 控制台执行:

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

    如果您没有管理权限,请跳过此步骤。您将回退到使用 Windows/应用程序日志

  2. 创建要在事件上执行的任务计划程序任务,例如,ID = 2020、Log = 'Automations' 和 Source = 'Automations'。在那里,您可以使用所有必要的权限调用您喜欢的任何内容

  3. 准备代码以发送您的事件,同时处理 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)
    
  4. 利润

于 2020-08-18T22:00:07.097 回答