从不同的线程访问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 } }