从不同的线程访问HttpContext.Current
我有一个C#ASP.NET应用程序,它启动大约25个不同的线程,在名为SiteCrawler.cs的类中运行一些方法。
在HttpContext.Current.Session
我想保存用户所做的search结果,并在所有线程完成运行时将其呈现给用户。 我的问题是HttpContext.Current
对象在派生线程中为null,因为它不存在。
由于应用程序是multithreading的限制,还有什么其他选项可以在不使用会话的情况下保存用户/会话特定数据?
我试图search周围的每一个Stackoverflowfind一个解决scheme,但没有任何运气….
在我的应用程序中有很多使用HttpContext.Current
的代码,我无法修改该代码。
下面的示例中的worker.DoWork()
使用该代码。 我必须在单独的线程中运行它。
我来到以下解决scheme:
HttpContext ctx = HttpContext.Current; Thread t = new Thread(new ThreadStart(() => { HttpContext.Current = ctx; worker.DoWork(); })); t.Start(); // [... do other job ...] t.Join();
看看这篇Fritz Onion的文章: 在服务器端Web代码中使用线程和构buildasynchronous处理程序 。 这是相当长的,但你的要求是不是太微不足道。
另外K. Scott Allen发表了一篇关于这个问题的文章,内容是: 使用HttpContext.Current
@Rory在上面做了一个评论,即使你将它传递给线程, HttpContext
中的某些对象也将变为null。 User
属性发生在我身上。 所以相反,你可以将用户复制到CurrentPrincipal这样的线程:
在控制器上下文中,保存用户:
_user = HttpContext.Current.User; var processThread = new Thread(() => ThreadedCode()); processThread.Start();
在线程中,设置“线程”用户:
private static void ThreadedCode() { // Workaround for HttpContext.Current.User being null. // Needed for CreatedBy and RevisedBy. Thread.CurrentPrincipal = _user;
请注意,HttpContext只能在请求的生命周期中使用。 线程将会比请求更长,这可能就是为什么你需要一个线程的原因! 🙂
你可以把它保存到数据库中,然后你可以让用户的浏览器保持刷新或者使用ajax或者使用新的信号来检查结果是否已经用db写入。 希望它有帮助。
只需将HttpContext.Current添加到类SiteCrawler.cs的构造函数中即可
public class SiteCrawler { HttpContext context = HttpContext.Current; public void Method() { context.WhateverYouWant } }