我有一个C#ASP.NET应用程序,它启动大约25个不同的线程,在一个名为SiteCrawler.cs的类中运行一些方法。
在HttpContext.Current.Session
中我想保存用户进行搜索的结果,并在所有线程完成运行时将其呈现给用户。我的问题是,HttpContext.Current
对象在生成的线程中为空,因为它不存在。
由于应用程序是多线程的限制,我还有哪些其他选项可以在不使用会话的情况下保存用户/会话特定数据?
我试图搜索Stackoverflow的每一寸都找到一个解决方案,但没有任何运气....
答案 0 :(得分:66)
在我的应用程序中,有很多代码使用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();
答案 1 :(得分:11)
看看Fritz Onion的这篇文章:Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code。这很长,但你的要求不是太微不足道。
K. Scott Allen也发表了一篇关于这个问题的文章:Working With HttpContext.Current
答案 2 :(得分:6)
@Rory在上面做了评论,即使你将它传递给线程,HttpContext
中的某些对象也会变为空。 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仅在请求的生命周期内可用。该线程可能比请求更长时间存在,这可能是您首先需要一个线程的原因! :)
答案 3 :(得分:4)
只需将HttpContext.Current添加到类SiteCrawler.cs的构造函数中
public class SiteCrawler
{
HttpContext context = HttpContext.Current;
public void Method()
{
context.WhateverYouWant
}
}
答案 4 :(得分:3)
您可以将其保存到数据库中,然后,您可以让用户的浏览器继续刷新或使用ajax或使用新的信号器检查结果是否已写入db。希望它有所帮助。