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

例子:

public class HttpModule : IHttpModule
{
    //...

    Dictionary<int, int> foo;

    void UseFoo(int a, int b)
    {
        foo[a] = b;
    }
}
有帮助吗?

解决方案

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

其他提示

我想在这里提出我关于这个问题的调查结果,我在IIS6已经观察到的:

我已经被广泛应用在IIS6处理这个问题,并发现利用log4net的和反射来捕获执行历史的一些有趣的结果。我发现是,有广泛的“线程管理”走出幕后。它似乎有一个“主”系列对应1线:1至HttpApplication。然而,这些线程没有专门处理您的请求管道。各种不同的子线程的可以在这些实例被访问被调用。后续新的请求,并通过您的应用程序所使用的资源请求似乎共享与您的原始请求一些持久信息但尚未从未初始线程指明某种关系的完全处理。我无法辨别(比我以前所描述的其他)任何具体的图案哪个元素被瓜分到其他线程,因为它是看似随意的。我的结论,这方面的证据是,有层次统筹的一些概念?发生,其中参考元件的一些未知子集被通过父参照继承在子线程。

因此,作为一个答案我会说,HttpModules线程之间共享。在锁定实例值而言,如果值适用于使用的模块,并且必须保持一定的状态,所有的请求,这将是适用的。我可以看到这一点,如果试图保持其是确定,以便他们能在后续请求中重复使用昂贵的状态实例的值是有用的。

这个问题已经困扰了我一段时间希望这个信息可以帮助别人。

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

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

发表吉姆文章很有趣,但正如吉姆说,它没有提及线程安全的事情。

我想,如果要初始化静态成员或执行你只需要锁定机构“只许一次”初始化即初始化静态资源。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top