HttpModule是否在工作线程之间共享?

时间:2010-04-11 23:08:26

标签: asp.net iis multithreading httpmodule ihttpmodule

我是否必须锁定对实例成员的访问权限?

示例:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

    void UseFoo(int a, int b)
    {
        foo[a] = b;
    }
}

4 个答案:

答案 0 :(得分:4)

从MSDN文档到目前为止,我不是很清楚,但我找到了forum post from someone who claims to know the answer。听起来你不应该期望糟糕的东西与你的实现一起发生,但你应该知道foo的状态不一定会在所有结果中共享,因为你的{{1将按照IIS选择保留在其池中的HttpModule创建一次。

答案 1 :(得分:1)

我最近发现了一篇稍微触及这个问题的文章: http://www.dominicpettifer.co.uk/Blog/41/ihttpmodule-gotchas---the-init---method-can-get-called-multiple-times

它没有提到线程,只是说工作进程

  

实例化尽可能多的HttpApplication   那些对象,因为它认为它需要   它会将它们用于表现   原因,将实例重用为新的   请求在发送之前进入   回到游泳池。

从链接中输入代码后,您可以确保以线程安全的方式执行一次初始化代码:

private static bool HasAppStarted = false; 
private readonly static object _syncObject = new object(); 

public void Init(HttpApplication context) 
{ 
    if (!HasAppStarted) 
    { 
        lock (_syncObject) 
        { 
            if (!HasAppStarted) 
            { 
                // Run application StartUp code here 

                HasAppStarted = true; 
            } 
        } 
    } 
}

我一直想设置一个测试应用程序来运行它并测试它,只是为了看它是否属实,但我没有时间。

答案 2 :(得分:1)

Jim发表的文章很有意思,但正如吉姆所说,它没有提及有关线程安全的任何内容。

我猜你只需要初始化静态成员或执行“一次”初始化,即初始化静态资源,就只需要锁定机制。

我无法从MSDN或Jim提到的文章中得出结论,我们在初始化非静态类变量时需要锁定机制。

答案 3 :(得分:1)

我想在这里提供我在IIS6中观察到的与此问题相关的发现:

我一直在IIS6中广泛处理这个问题,并且发现了一些利用log4net和反射来捕获执行历史的有趣结果。我发现在幕后有广泛的“线程管理”。似乎有一个'主要'系列线程对应1:1到HttpApplication。但是,这些线程并不专门为您的请求处理管道。访问这些实例时,可以调用各种不同的子线程 。您的应用程序使用的后续新请求和资源请求似乎共享一些与您的原始请求相关的持久性信息,但从未完全由初始线程处理,表明某种类型的关系。我无法辨别出任何具体的模式(除了我之前描述过的)关于哪些元素被分配给其他线程,因为它看起来是随机的。我对这个证据的结论是,有一些分层汇集的概念?发生在子线程中通过父引用继承某些未知的引用元素子集的地方。

作为答案,我会说线程之间共享HttpModules 。在锁定实例值方面,如果值适用于使用该模块的所有请求并且必须保持某种状态,则这将适用。如果尝试维护有价值的有状态实例值,我可以看到这很有用,以便在后续请求中重用它们。

这个问题让我困扰了一段时间,希望这些信息有助于某人。