【问题标题】:Thread in Code behind后台代码中的线程
【发布时间】:2010-06-23 11:41:57
【问题描述】:
我有一个 aspx.cs 页面和一个对应的 aspx 页面。加载此页面时,在按钮事件上,我创建了一个运行一段时间然后退出的线程。我想知道谁是这个线程的父级。
假设线程正在运行,我关闭了这个页面,这个线程会退出吗?
我这样做了,但线程一直在运行。
实际上我想做的是在用户关闭页面时清理任务。
w3wp 是这个线程的父级吗?
如果没有那么,如果我关闭此页面,谁将成为父母?
【问题讨论】:
标签:
c#
.net
asp.net
multithreading
【解决方案1】:
线程没有父级。特别是,父母的“死亡”对他们来说毫无意义。
您可能遇到的一个问题是您的线程方法可能依赖于特定于页面或请求的数据。任何依赖于HttpContext 的东西都会有问题,因为在请求结束后线程仍然可以运行,HttpContext 不再有效。让线程依赖页面上的任何内容也是如此,因为页面在请求完成后被销毁。
请参阅“Wicked Code: Asynchronous Pages in ASP.NET 2.0”以了解 ASP.NET 页面中异步操作的良好模式。这就是页面意味着与异步世界交互的方式。
【解决方案2】:
不推荐代表用户运行线程。如果可能,我建议您查看您网站的异步页面。
如果您确实需要一个线程,那么您必须通过会话 ID 创建一个线程查找(例如,Dictionary<string, Thread>)。启动线程时,将其存储在字典中(当前会话 id 为Session.SessionID)。当会话结束时(Global.aspx 中的Session_OnEnd),告诉线程停止并将其从字典中删除。
记得锁定你的字典对象。
【解决方案3】:
由于您的浏览器和您的网络服务器除了您实际发出请求的奇数次之外没有任何连接,因此 ASP.NET 或 IIS 无法检测到您的浏览器窗口何时关闭。您唯一能做的就是检测会话结束。由于您表示您只想进行清理,并且由于我不确定在 Session_OnEnd 处理程序中执行长时间运行的操作是否是个好主意,因此您可能想要使用线程池:
protected void Session_OnEnd(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(CleanUpSession, myStateObject);
}
private void CleanUpSession(object state)
{
// do your clean-up here
}