ThreadStatic的奇怪行为

时间:2010-08-12 09:38:23

标签: c# .net multithreading

我有代码:

internal static class IdCounter
{
    [ThreadStatic]
    private static int _id = 0;

    static IdCounter()
    {

    }

    public static int Id
    {
        get
        {
            lock(typeof(IdCounter))
            {
                return _id++;
            }
        }
    }
}

public abstract class Request
{
    protected Request(int requestId)
    {
        RequestId = IdCounter.Id;
    }
}

在第二次通话中,我收到RequestId等于2,而不是1,问题出在哪里?我试图使用Thread.SetData,但结果是一样的。

2 个答案:

答案 0 :(得分:5)

(之前的回复已删除;我认为这可能是一个红色的鲱鱼。)

为了回应有点神秘的评论,你的意思是在第一次请求时你希望得到0,在第二次请求得到1吗?如果是这样,我根本看不出这与_ThreadStatic有什么关系。我不相信RequestId只会在两个请求之后返回2,即使是在同一个线程上,除非你看到奇怪的调试器效果。如果您认为自己看到了一些奇怪的行为,请发布简短但完整的计划来证明问题。

请注意,由于您有一个增加计数器的属性,如果您在调试器中单步执行,它可能会在您不期望它时评估该属性 - 即使您没有明确地查看{ {1}}财产。这可以解释发生了什么。尝试使用调试器重现问题而不使用

理想情况下,编写幂等属性 - 如果你编写具有副作用的属性,在调试时你总是会遇到奇怪的风险,以及代码中的微妙错误(你可能会重构两个属性访问一个,不知道副作用)。

答案 1 :(得分:3)

您是否在调试器中检查IdCounter.Id的值?这将评估属性,这将增加它。

修改属性获取操作是一个坏主意。

此外:

  • 使用类型实例进行锁定是一个坏主意(指南建议不要使用它,因为它可能会在某些情况下导致问题),而是分配一个Object实例来锁定。
  • 如果_idThreadStatic,每个线程都有自己的实例,所以无论如何都不需要锁定。