2

一部の静的メソッドでは、操作中に小さな配列を使用して値を一時的に格納すると非常に便利であることがわかりました。この配列は、インデックス付けが必要なため便利ですが、メソッドが呼び出されるたびにその小さな配列が割り当てられます。

これは、C# に C のような静的ローカルがないことを回避する良い方法ですか?

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

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

私の仮定では、直接 (再帰的) または間接的に自分自身を呼び出すことができないメソッドは、単一のスレッドでのみ呼び出すことができるため、偽の静的ローカルをスレッド静的と宣言する必要があり、問題は大幅に解決されます。

編集:

レジスタの内容は、メソッド呼び出し間でガベージであることを付け加える必要があります。

4

1 に答える 1

3

それは私が良い回避策と呼ぶものではありません。それは機能します(再入可能性のリスクについて確信がある場合、つまり、偶発的なイベント/コールバック/などを介しても、それ自体を呼び出さないと仮定します)-しかし...

私の意見では、それはステートフルで、インスタンスにします:

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

WheverTheTypeIsコンテキストごとに異なるインスタンスを使用するだけです。つまり、インスタンスがコンテキストとして機能します。スレッドごとにコンテキストが必要な場合は、スレッドごとに異なるインスタンスを使用してください。これにより、コールバック、並列処理、ワーカーなどを使用して、同じコンテキストで継続することもできます。単一のスレッド (WCF、ASP.NET、WPF など) を保証しないフレームワークが多数あることに注意してください。これは、5.0 でより多くのasync/await指向のコードが導入されるにつれて増加するだけです。

静的メソッドに深く結びついている場合は、registerin を 2 番目のパラメーターとして渡すだけでも十分です。

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

問題が 4 バイト配列の割り当てである場合:

  1. それは通常GEN-0になるので、収集するのが安い
  2. 本当に必要な場合は、 stackallocandを使用しunsafeて割り当てを回避します

「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];
    ....
}
于 2011-11-05T22:47:07.523 に答える