从不同的线程访问HttpContext.Current

时间:2012-01-19 11:26:18

标签: c# asp.net session httpcontext

我有一个C#ASP.NET应用程序,它启动大约25个不同的线程,在一个名为SiteCrawler.cs的类中运行一些方法。

HttpContext.Current.Session中我想保存用户进行搜索的结果,并在所有线程完成运行时将其呈现给用户。我的问题是,HttpContext.Current对象在生成的线程中为空,因为它不存在。

由于应用程序是多线程的限制,我还有哪些其他选项可以在不使用会话的情况下保存用户/会话特定数据?

我试图搜索Stackoverflow的每一寸都找到一个解决方案,但没有任何运气....

5 个答案:

答案 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。希望它有所帮助。