我有一个C#ASP.NET应用程序,它启动了大约25个不同的线程,在一个名为SiteCrawler.cs的类中运行一些方法。
在HttpContext.Current.Session
中,我想保存用户进行的搜索结果,并在所有线程完成运行时将其呈现给用户。我的问题是HttpContext.Current
对象在生成的线程中为null,因为它在那里不存在。
由于应用程序是多线程的限制,我还有什么其他选项来保存用户/会话特定数据而不使用会话?
我试图搜索Stackoverflow的每一寸都找到一个解决方案,但没有任何运气....
在我的应用程序中有很多代码使用HttpContext.Current
,我无法修改该代码。
以下示例中的worker.DoWork()
使用该代码。而且我必须在单独的线程中运行它。
我来到以下解决方案:
HttpContext ctx = HttpContext.Current;
Thread t = new Thread(new ThreadStart(() =>
{
HttpContext.Current = ctx;
worker.DoWork();
}));
t.Start();
// [... do other job ...]
t.Join();
看看Fritz Onion的这篇文章:Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code。这很长,但你的要求不是太微不足道。
K. Scott Allen也发表了一篇关于这个问题的文章:Working With 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仅在请求的生命周期内可用。该线程可能比请求更长时间存在,这可能是您首先需要一个线程的原因! :)
只需将HttpContext.Current添加到类SiteCrawler.cs的构造函数中
public class SiteCrawler
{
HttpContext context = HttpContext.Current;
public void Method()
{
context.WhateverYouWant
}
}
您可以将其保存到数据库,然后,您可以让用户的浏览器继续刷新或使用ajax或使用新的信号器检查结果是否已写入db。希望能帮助到你。