我需要执行一个无限的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
答案 0 :(得分:15)
ASP.NET不是为处理这种要求而设计的。如果你需要不断运行的东西,你最好创建一个Windows服务。
更新
ASP.NET不适用于长时间运行的任务。它旨在快速响应HTTP请求。有以下原因,请参阅Cyborgx37's answer或Can I use threads to carry out long-running jobs on IIS?。
更新
既然你最后提到你正在使用SignalR,我看到你正在尝试在ASP.NET中托管SignalR,对吗?我认为你的方法是错误的,请参阅NuGet package上引用的示例project wiki。此示例使用IAsyncHttpHandler
来管理任务。
答案 1 :(得分:10)
你可以在你的global.asax中启动一个线程,但它只会运行直到你的asp.net进程被回收。这将至少每天发生一次,或者当没有人使用您的网站时。如果进程被回收,那么线程重新启动的唯一方法就是在您的站点上点击时。所以线程没有继续运行。
要获得继续进程,最好启动Windows服务。
如果您执行“进行中”解决方案,它实际上取决于您正在做什么。线程本身不会导致内存或死锁问题。你应该添加一个meganism来停止你的线程在应用程序停止时。否则重启将花费很长时间,因为它会等待你的线程停止。
答案 2 :(得分:3)
这是一篇很老的帖子,但是当我正在搜索这篇文章时,我想报告一下,在.NET 4.5.2中,有一种使用QueueBackgroundWorkItem的本地方法。
MarianoC
答案 3 :(得分:2)
这取决于你在while循环中想要完成的事情,但总的来说这是Windows Service是最佳答案的情况。安装Windows服务将要求您具有Web服务器的管理员权限。
对于无限循环,您最终会遇到很多关于Windows消息泵的问题。即使应用程序没有“正在”执行任何操作,这也可以使Windows应用程序保持活动状态。没有它,程序就会结束。
无限循环的问题是应用程序被“做”某事,这会阻止其他应用程序(或线程)“做”他们的事情。有一些解决方法,例如Windows窗体中的DoEvents,但它们在响应性和资源管理方面都有一些严重的缺点。 (可以在小型LOB应用程序上接受,也可能不在Web服务器上。)即使while循环位于单独的线程上,它也会耗尽所有可用的处理能力。
Asynchronus编程实际上是为长时间运行的进程设计的,例如等待数据库返回结果或等待打印机联机。在这些情况下,外部过程需要很长时间,而不是一个循环。
如果无法使用Window Service,那么我认为您最好的选择是使用自己的消息泵设置一个单独的线程,但它有点复杂。我从未在Web服务器上完成它,但您可以启动应用程序。这将为您提供消息泵,并允许您响应Windows事件等。唯一的问题是这将启动Windows应用程序(WPF或WinForms),这可能不会在网络服务器上是可取的。
你想要完成什么?还有另外一种方法吗?
答案 4 :(得分:1)