使用threadstatic静态字段模拟函数静态变量?

时间:2011-11-05 22:31:59

标签: c# static thread-safety local-variables

对于某些静态方法,我意识到在操作期间使用小数组临时存储值非常方便。所述数组很有用,因为您需要建立索引,但每次调用该方法时都会分配该小数组。

这个是解决C#中缺少类C静态本地的好方法吗?

[ThreadStatic]private static int[] staticregister = new int[4];

public static bool CoolStaticMethod(int[] largearray)
{
    //...
}

我的假设是一个不能直接(递归)或间接调用自身的方法只能在一个线程中单独调用,因此假静态局部应该被声明为线程静态而问题更大解决。

编辑:

我必须补充说,寄存器的内容在方法调用之间是垃圾。

1 个答案:

答案 0 :(得分:3)

我称之为好的解决方法,不是。它将工作(假设您确定重新入侵的风险,即即使是通过意外事件/回调等等也不会自我调用) - 但是......

在我的意见中,它是有状态的,使其成为实例

private int[] register = new int[4];
public bool CoolMethod(int[] largearray) {...}

并简单地为每个上下文使用WheverTheTypeIs的不同实例,即实例行为作为上下文。如果您想要每个线程的上下文,只需为每个线程使用不同的实例。这也允许使用回调,并行,工作等在相同上下文中继续使用。请注意,有许多框架不保证单个线程(例如WCF,ASP.NET,WPF),并且这只会随着5.0引入更多async / await面向代码而增加

如果你与静态方法紧密相关,那么将register作为第二个参数传递就足够了:

public static bool CoolStaticMethod(int[] largearray, int[] register) {...}

如果问题是分配4字节数组:

  1. 通常是GEN-0,收藏便宜
  2. 如果您真的想要,请使用stackallocunsafe来避免分配
  3. 以“2”为例:

    public static unsafe bool CoolStaticMethod(int[] largearray)
    {
        // not an array! this is raw data on the stack; DO NOT GO OUT OF BOUNDS!
        int* register = stackalloc int[4]; 
    
        register[0] = 1;
        register[1] = largearray[3];
        largearray[2] = register[0];
        ....
    }