5

GetAllFoo()WCF クライアント アプリケーションには、結果をキャッシュしたいパラメーターなしのメソッドが多数ありますGetAllBar()。これらはドロップダウンなどに入力するために使用され、結果はクライアントの実行中は変更されません。

これらの結果は現在、リソース ファイルに格納されている一意の文字列によってキャッシュされています。たとえば、リソースGetAllCountries()に対してキャッシュされていCountryKeyます。このサービスは、要求されたキーがキャッシュに含まれていない場合にのみ呼び出されます。

public T Get<T, V>(string key, Func<V, T> serviceCall, V proxy)
{
    if (!cache.Contains(key))
    {
        cache.Add(key, serviceCall(proxy));
    }   
    return cache.GetData(key) as T;
}

これは問題ありませんが、リソース ファイルでキーを維持する必要があり、すべてのメソッドが正しいキャッシュ キーを使用していることを確認する必要があります。そうしないと、問題が発生します。古い Control+C、Control+V はここでいくつかの頭痛の種を引き起こします。このメソッドを呼び出すすべての場所をチェックする必要はありません。

だから質問:

serviceCallデリゲートには、実行Methodするメソッドを記述するプロパティがあります。MethodHandleこれは、プロパティを含む MethodInfo インスタンスです。MethodHandleプロパティが参照されるメソッドを一意かつ一貫して識別すると仮定するのは正しいですか?

ラッパーを次のように変更します

public T Get<T, V>(Func<V, T> serviceCall, V proxy)
{
    var key = serviceCall.Method.MethodHandle;
    // etc

これにより、キャッシュと重要な問題が適切にカプセル化され、「正しいことを行う」呼び出し元への依存がなくなります。

  • MethodHandle がインスタンス間で変更されても気にしないでください - キャッシングはインスタンスごとにのみ行われます
  • MethodHandle がクライアント間で一貫していなくてもかまいません - キャッシングはクライアントごとです
  • MethodHandleがクライアントのインスタンス内で一貫していない場合は注意してください。実際には、すべてのリクエストで新しいサービスが呼び出され、キャッシュが未使用のデータでいっぱいになるのではなく、キャッシュを使用する必要があります。
  • MethodHandleがクライアントのインスタンス内で一意でない場合は注意してください。ラッパーを使用するときに正しいデータ (および型) が返されるようにする必要があります。
4

1 に答える 1

2

MethodHandle プロパティについて言及している MSDN は、「このプロパティは、アンマネージ コードからマネージ クラスにアクセスするためのものであり、マネージ コードから呼び出すべきではありません」と述べています。

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices._methodbase.methodhandle.aspx

提案:

  • 同じ AppDomain 内で一意であると想定されているため、とにかく serviceCall.Method.MethodHandle を使用してください。
  • serviceCall.Method.GetHashCode() を調べて、これがキャッシュ キーとして機能するかどうかを確認してください。
  • キャッシング メカニズムをディクショナリ T> に変更し、serviceCall を実際のキャッシング キーとして使用します。(これは、コードがラッパー メソッドを呼び出す方法によっては機能しない場合があります。)
于 2011-03-07T01:25:29.887 に答える