从不同的线程访问HttpContext.Current

问题描述 投票:49回答:5

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

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

由于应用程序是多线程的限制,我还有什么其他选项来保存用户/会话特定数据而不使用会话?

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

c# asp.net session httpcontext
5个回答
71
投票

在我的应用程序中有很多代码使用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();

11
投票

看看Fritz Onion的这篇文章:Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code。这很长,但你的要求不是太微不足道。

K. Scott Allen也发表了一篇关于这个问题的文章:Working With HttpContext.Current


7
投票

@Rory在上面做了一个评论,即使你把它传递给线程,HttpContext中的某些对象也会变为null。这发生在User财产上。因此,您可以将用户复制到线程CurrentPrincipal,如下所示:

In the controller context, save off the user:

            _user = HttpContext.Current.User;
            var processThread = new Thread(() => ThreadedCode());
            processThread.Start();

In the thread, set the 'Thread's' user:

    private static void ThreadedCode()
    {
        // Workaround for HttpContext.Current.User being null.
        // Needed for CreatedBy and RevisedBy.
        Thread.CurrentPrincipal = _user;

请注意,HttpContext仅在请求的生命周期内可用。该线程可能比请求更长时间存在,这可能是您首先需要一个线程的原因! :)


4
投票

只需将HttpContext.Current添加到类SiteCrawler.cs的构造函数中

public class SiteCrawler
{
     HttpContext context = HttpContext.Current;

    public void Method()
    {
        context.WhateverYouWant
    }
}

3
投票

您可以将其保存到数据库,然后,您可以让用户的浏览器继续刷新或使用ajax或使用新的信号器检查结果是否已写入db。希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.