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

发布于 2024-08-28 07:25:02 字数 213 浏览 14 评论 0原文

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

例子:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

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

Do I have to lock access to instance members?

Example:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

铜锣湾横着走 2024-09-04 07:25:02

到目前为止,MSDN 文档对我来说还不是很清楚,但我找到了 来自声称知道答案的人的论坛帖子。听起来您不应该期望您的实现会发生坏事,但您应该意识到 foo 的状态不一定会在所有结果之间共享,因为您的HttpModule 将针对 IIS 选择保留在其池中的每个 HttpApplication 创建一次。

It's not crystal clear to me so far from the MSDN documentation, but I found a forum post from someone who claims to know the answer. It sounds like you shouldn't expect bad stuff to happen with your implementation, but you should be aware that foo's state will not necessarily be shared across all results since your HttpModule will be created once per HttpApplication that IIS chooses to keep in its pool.

冷了相思 2024-09-04 07:25:02

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

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

因此,作为答案,我会说 HttpModules 在线程之间共享。就锁定实例值而言,如果这些值适用于使用该模块并且必须维护某种状态的所有请求,则这将是适用的。如果尝试维护有状态实例值(确定这些值的成本很高,以便可以在后续请求中重用它们),我可以看到这很有用。

这个问题已经困扰我一段时间了,希望这些信息对某人有所帮助。

I wanted to offer here my findings related to this question as I have observed in IIS6:

I have been dealing with this issue extensively in IIS6 and have found some interesting results utilizing log4net and reflection to capture execution history. What I have found is that there is extensive 'thread management' going on behind the scenes. It seems that there is a 'primary' series of threads that corresponds 1:1 to HttpApplication. These threads however to do not exclusively handle the pipeline for your request. Various different sub-threads can be called when these instances are accessed. Subsequent new requests and resource requests utilized by your application seem to share some persistent information relating to your original request but are yet never handled entirely by the initial thread indicating some type of relationship. I could not discern any concrete pattern (other than what i've previously described) as to which elements were divvied to other threads as it was seemingly random. My conclusion to this evidence is that there is some concept of hierarchical pooling? occurring where some unknown subset of reference elements are inherited in the child threads through the parent reference.

So as an answer I would say that HttpModules are shared between threads. In terms of locking instance values, this would be applicable if the values apply to all requests which use the module and must maintain some state. I could see this being useful if attempting to maintain stateful instance values which are expensive to ascertain so that they could be reused in subsequent requests.

This issue had been troubling me for some time hopefully this info helps someone.

浪荡不羁 2024-09-04 07:25:02

最近发现一篇文章稍微涉及到这个问题:
http://www.domincpettifer.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; 
            } 
        } 
    } 
}

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

I recently found an article which touches on this question slightly:
http://www.dominicpettifer.co.uk/Blog/41/ihttpmodule-gotchas---the-init---method-can-get-called-multiple-times

It doesn't mention threads, but only says that the worker process will

instantiate as many HttpApplication
objects as it thinks it needs, then
it'll pool them for performance
reasons, reusing instances as new
requests come in before sending them
back into the pool.

Following the code in from the link, you can be sure that your init code is executed once in a thread-safe manner:

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; 
            } 
        } 
    } 
}

I've been meaning to set up a test app to run this and test it, just to see if it's true, but I haven't had the time.

唔猫 2024-09-04 07:25:02

Jim 发布的文章很有趣,但正如 Jim 所说,它没有提到任何有关线程安全的内容。

我想如果您正在初始化静态成员或执行“仅一次”初始化(即初始化静态资源),则只需要锁定机制。

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

The article posted by Jim is interesting, but as Jim says it does not mention anything about thread safety.

I guess you would only need the lock mechanism if you are initializing static members or performing "only once" initializations i.e. initializing a static resource.

I couldn't conclude from MSDN nor the article mentioned by Jim that we need the lock mechanism when initializing non-static class variables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文