C# 使用threadstatic字段模拟函数静态变量?
对于一些静态方法,我意识到在操作期间使用一个小数组临时存储值是非常方便的。所述数组很有用,因为您需要索引,但每次调用该方法时都会分配该小数组 这是解决C#中缺少类似C的静态局部变量的好方法吗 我的假设是,一个不能直接(递归)或间接调用自身的方法只能在单个线程中单独调用,因此伪静态局部应该声明为线程静态,问题得到了很大的解决 编辑: 我必须补充一点,在方法调用之间,寄存器的内容是垃圾。这不是我所说的一个好的解决方法,不。它会起作用(假设您确信重入风险,即即使通过意外事件/回调/等,也不会调用自身)-但是 在我看来,它是有状态的,让它成为一个实例:C# 使用threadstatic字段模拟函数静态变量?,c#,static,thread-safety,local-variables,C#,Static,Thread Safety,Local Variables,对于一些静态方法,我意识到在操作期间使用一个小数组临时存储值是非常方便的。所述数组很有用,因为您需要索引,但每次调用该方法时都会分配该小数组 这是解决C#中缺少类似C的静态局部变量的好方法吗 我的假设是,一个不能直接(递归)或间接调用自身的方法只能在单个线程中单独调用,因此伪静态局部应该声明为线程静态,问题得到了很大的解决 编辑: 我必须补充一点,在方法调用之间,寄存器的内容是垃圾。这不是我所说的一个好的解决方法,不。它会起作用(假设您确信重入风险,即即使通过意外事件/回调/等,也不会调用自身)
private int[] register = new int[4];
public bool CoolMethod(int[] largearray) {...}
当类型为每个上下文时,只需使用不同的实例,即实例作为上下文。如果需要每个线程的上下文,只需为每个线程使用不同的实例即可。这还允许在相同的上下文中继续使用回调、并行、工作进程等。请注意,有许多框架不保证单个线程(例如WCF、ASP.NET、WPF),这只会随着5.0引入更多面向async
/wait
的代码而增加
如果您深深地依赖于静态方法,那么将寄存器作为第二个参数传入也就足够了:
public static bool CoolStaticMethod(int[] largearray, int[] register) {...}
如果问题是4字节数组的分配:
这通常是第0代,收集起来很便宜
如果您确实需要,请使用stackalloc
和safe
避免分配
关于“2”的示例:
对[只是一个可以发表评论的填充者]您关于传递工作缓冲区/寄存器的建议只会使依赖于静态方法服务的客户端代码的设计变得复杂。@Cecil k;最后一个建议是什么,如果问题是分配一个小数组(顺便说一句,我真的认为你不需要担心)@Cecil plus,如果你考虑分配,你可以用一个微池来避免;如果你想要一个例子,请告诉我。老实说,我最初对分配滞后和GC’ing的担心并不是很关键,直到我做了一些分析,以确定这实际上可能是一个问题。据我所知,JIT和GC可以查看使用模式并在堆栈上分配数组,然后在返回时将其弹出。@Cecil它不会这样做(除非您使用stackalloc)-但是,它将在GEN-0上分配,在GEN-0上死亡,这是非常便宜的检查。当然,这取决于使用情况,但我不会对此感到困扰,除非它被称为“很多”。
public static bool CoolStaticMethod(int[] largearray, int[] register) {...}
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];
....
}