19

我需要执行一个无限的 while 循环并希望在global.asax. 我的问题是我应该怎么做?我应该开始一个新线程还是应该使用 Async 和 Task 或其他任何东西?在while循环内我需要做 await TaskEx.Delay(5000);

我该如何做到这一点,这样它就不会阻塞任何其他进程并且不会造成内存泄漏?

我使用 VS10、AsyncCTP3、MVC4

编辑:

 public void SignalRConnectionRecovery()
        {
            while (true)
            {
                Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString());
                await TaskEx.Delay(5000);
            }
        }

只要应用程序可用,我需要做的就是在全局范围内将其作为单例实例运行。

编辑:已解决

这是 Global.asax 中的最终解决方案

protected void Application_Start()
{
    Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery);
    signalRConnectionRecovery.IsBackground = true;
    signalRConnectionRecovery.Start();

    Application["SignalRConnectionRecovery"] = signalRConnectionRecovery;
}


protected void Application_End()
{
    try
    {
        Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"];
        if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive)
        {
            signalRConnectionRecovery.Abort();
        }
    }
    catch
    {
            ///
    }
}

我发现这篇关于如何使用异步工作者的好文章:http: //www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

这: http ://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

但我认为对于我的需要,这将是完美的: http ://forums.asp.net/t/1433665.aspx/1

4

5 回答 5

15

ASP.NET 不是为处理这种要求而设计的。如果你需要一些东西来持续运行,你最好创建一个 Windows 服务。

更新

ASP.NET 不是为长时间运行的任务而设计的。它旨在快速响应 HTTP 请求。请参阅Cyborgx37 的答案我可以使用线程在 IIS 上执行长时间运行的作业吗?有几个原因。

更新

现在您终于提到您正在使用 SignalR,我看到您正在尝试在 ASP.NET 中托管 SignalR,对吗?我认为您以错误的方式进行此操作,请参阅项目 wiki上引用的示例NuGet 包。此示例使用来管理任务。IAsyncHttpHandler

于 2012-06-01T14:51:18.907 回答
10

您可以在 global.asax 中启动一个线程,但它只会运行到您的 asp.net 进程被回收。这将至少每天发生一次,或者在没有人使用您的网站时发生。如果进程被回收,线程重新启动的唯一方法是在您的站点受到点击时。所以线程没有继续运行。

要获得一个持续的过程,最好启动一个 Windows 服务。

如果您执行“进行中”解决方案,这实际上取决于您在做什么。线程本身不会给您带来任何内存问题或死锁。您应该添加一个机制以在应用程序停止时停止您的线程。否则重启需要很长时间,因为它会等待你的线程停止。

于 2012-06-01T14:53:58.960 回答
5

这是一篇旧文章,但是当我为此搜索时,我想报告在 .NET 4.5.2 中有一种使用 QueueBackgroundWorkItem 的本地方法。

看看这篇文章:https ://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/

马里亚诺

于 2014-07-31T11:14:20.020 回答
2

这取决于您在 while 循环中尝试完成的任务,但一般来说,在这种情况下,Windows 服务是最佳答案。安装 Windows 服务需要您在 Web 服务器上具有管理员权限。

对于无限循环,您最终会遇到很多关于 Windows 消息泵的问题。即使应用程序没有“做”任何事情,这也是使 Windows 应用程序保持活力的东西。没有它,程序就会结束。

无限循环的问题是应用程序被卡在“做”某事,这会阻止其他应用程序(或线程)“做”他们的事情。有一些解决方法,例如 Windows 窗体中的 DoEvents,但在响应性和资源管理方面它们都有一些严重的缺陷。(在小型 LOB 应用程序上可以接受,但在 Web 服务器上可能不行。)即使 while 循环在单独的线程上,它也会耗尽所有可用的处理能力。

异步编程实际上是为长时间运行的进程设计的,例如等待数据库返回结果或等待打印机联机。在这些情况下,需要很长时间的是外部进程,而不是 while 循环。

如果无法使用窗口服务,那么我认为您最好的选择是设置一个带有自己的消息泵的单独线程,但这有点复杂。我从来没有在网络服务器上做过,但你也许可以启动一个应用程序。这将为您提供消息泵并允许您响应 Windows 事件等。唯一的问题是这将启动 Windows 应用程序(WPFWinForms),这在 Web 服务器上可能不理想。

你想达到什么目的?你还有其他方法可以解决吗?

于 2012-06-01T15:06:41.897 回答
1

我发现这篇关于如何使用异步工作者的好文章,将尝试一下。http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

这: http ://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

但我认为对于我的需要,这将是完美的: http ://forums.asp.net/t/1433665.aspx/1

于 2012-06-01T15:39:23.010 回答