我不知道IIS是否允许我的线程继续运行,即使用户会话已过期。 想象一下,用户触发事件,我们在服务器上实例化对象并在新线程中触发方法。用户收到“已提交您的请求”消息,并关闭浏览器。最终,该用户的会话将在IIS上超时,但线程可能仍在运行工作。IIS会允许线程继续运行还是会在用户会话过期后终止并释放该对象?
编辑(来自遥远的未来)- 如今我会使用Hangfire。
HostingEnvironment.RegisterObject
)。 - John我不同意被接受的答案。
在ASP.NET中,使用后台线程(或使用Task.Factory.StartNew
启动的任务)是可以的。与所有托管环境一样,您可能需要理解并配合管理关闭的设施。
在ASP.NET中,您可以使用HostingEnvironment.RegisterObject
方法注册需要在关闭时优雅地停止的工作。有关讨论,请参见此文章和评论。
(正如杰拉德在他的评论中指出的那样,现在也有HostingEnvironment.QueueBackgroundWorkItem
,它调用RegisterObject
来注册后台项目的调度器。总体而言新方法更好,因为基于任务)。
至于您经常听到的不好的想法的一般主题,请考虑部署Windows服务(或其他类型的额外进程应用程序):
还要注意,一些高级场景甚至需要在同一地址空间中运行后台线程。我认为ASP.NET能够做到这一点是通过.NET变得可能的一个巨大优势。
您不希望使用来自IIS线程池的线程来执行此任务,因为这会导致该线程无法处理未来的请求。您可以查看 ASP.NET 2.0中的异步页面,但那真的也不是正确的答案。相反,听起来您会受益于研究 Microsoft Message Queuing。基本上,您将任务详细信息添加到队列中,另一个后台进程(可能是Windows服务)将负责执行该任务。但最重要的是,后台进程与IIS完全隔离。
这里有一个很好的帖子和示例代码:http://forums.asp.net/t/1534903.aspx?PageIndex=2
我甚至考虑过从线程中调用我的网站上的保持活动页面,以帮助保持应用程序池的活跃。请记住,如果您使用此方法,则需要非常好的恢复处理,因为应用程序可能随时重新启动。正如许多人所提到的,如果您可以访问其他服务选项,则这不是正确的方法,但对于共享托管来说,这可能是您唯一的选择之一。
为了帮助保持应用程序池的活跃,您可以在线程正在处理时向自己的网站发出请求。如果您的进程运行时间很长,这可能有助于保持应用程序池的活跃。
string tempStr = GetUrlPageSource("http://www.mysite.com/keepalive.aspx");
public static string GetUrlPageSource(string url)
{
string returnString = "";
try
{
Uri uri = new Uri(url);
if (uri.Scheme == Uri.UriSchemeHttp)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
CookieContainer cookieJar = new CookieContainer();
req.CookieContainer = cookieJar;
//set the request timeout to 60 seconds
req.Timeout = 60000;
req.UserAgent = "MyAgent";
//we do not want to request a persistent connection
req.KeepAlive = false;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
StreamReader sr = new StreamReader(stream);
returnString = sr.ReadToEnd();
sr.Close();
stream.Close();
resp.Close();
}
}
catch
{
returnString = "";
}
return returnString;
}
您可以创建一个Windows服务来完成这项任务吗?然后使用.NET远程调用从Web服务器调用Windows服务执行操作?如果是这种情况,那就是我会做的。
这将消除对IIS的依赖,并限制其处理能力。
如果不是这样,那么我会强制用户在处理过程中坐在那里。这样可以确保它被完成并且不被IIS杀死。
在IIS中,似乎有一种支持长时间运行工作的方式。 工作流服务似乎是为此而设计的,特别是与Windows Server AppFabric结合使用。该设计支持自动持久化和恢复长时间运行的工作,从而允许应用程序池进行回收。