使用方法的MethodHandle作为键缓存无参数方法的结果是否安全?

时间:2021-08-22 20:45:39

In a WCF client application, there are a number of parameterless methods for which we'd like to cache the results - GetAllFoo() , GetAllBar(). These are used to populate dropdowns and the like, and the results don't change during the running life of the client.

在WCF客户端应用程序中,有许多无参数的方法,我们希望缓存结果—GetAllFoo()、GetAllBar()。它们用于填充下拉列表之类的内容,结果在客户端运行期间不会改变。

These results are currently being cached by a unique string stored in a Resource file - for example, GetAllCountries() is cached against the CountryKey Resource. The service is only called when the cache doesn't contain the requested key.

这些结果目前由存储在资源文件中的唯一字符串缓存—例如,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;
}

This is fine except we need to maintain the keys in the Resource file, and need to make sure that every method uses the correct cache key otherwise things break. The old Control+C, Control+V causes a few headaches here and I don't want to have to go check every place that calls this method.

这很好,但我们需要维护资源文件中的键,并需要确保每个方法都使用正确的缓存键,否则会发生故障。旧的控件+C, Control+V在这里会引起一些麻烦,我不想去检查每个调用这个方法的地方。

So the question:

问题:

The serviceCall delegate has a Method property on it which describes the method to execute. This is a MethodInfo instance, which in turn contains a MethodHandle property. Am I right in assuming that the MethodHandle property uniquely and consistently identifies the method that is referenced?

serviceCall委托具有一个方法属性,该属性描述要执行的方法。这是一个method dinfo实例,它反过来包含一个MethodHandle属性。我是否正确地假设MethodHandle属性唯一且一致地标识引用的方法?

I'd change the wrapper to

我把包装改成

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

which properly encapsulates the caching and key concerns, & removes any dependency on the caller 'doing the right thing'.

它恰当地封装了缓存和关键问题,并消除了对调用者“做正确的事情”的任何依赖。

  • Don't care if the MethodHandle changes between instances - the caching is only per instance
  • 不要在意方法是否在实例之间处理更改——缓存仅针对每个实例
  • Don't care if the MethodHandle is not consistent across clients - caching is per client
  • 不要担心方法句柄在客户端之间是否不一致——缓存是每个客户端
  • DO care if the MethodHandle is not consistent within an instance on a client - I actually want the cache to be used, rather than every request resulting in a new service call and the cache being full of unused data
  • 请注意,如果方法句柄在客户机上的实例中不一致——我实际上希望使用缓存,而不是导致新服务调用和缓存满是未使用的数据的每个请求
  • DO care if the MethodHandle is not unique within an instance on a client - I have to be sure that the correct data (and type) is returned when the wrapper is used.
  • 在客户端实例中,如果方法句柄不是唯一的,请注意——我必须确保在使用包装器时返回正确的数据(和类型)。

1 个解决方案

#1


2  

MSDN, referring to the MethodHandle property, says "this property is for access to managed classes from unmanaged code and should not be called from managed code."

MSDN引用MethodHandle属性,表示“此属性用于从非托管代码访问托管类,不应从托管代码调用。”

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

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

Suggestions:

建议:

  • Use serviceCall.Method.MethodHandle anyway since it is supposed to be unique within the same AppDomain.
  • 使用serviceCall.Method。MethodHandle,因为它应该在同一个AppDomain中是唯一的。
  • Research serviceCall.Method.GetHashCode() to see if this would work for you as your caching key.
  • 研究servicecall.method.method.gethashcode(),看看它是否适合作为您的缓存键。
  • Change your caching mechanism to be a Dictionary, T> and use serviceCall as the actual caching key. (This may not work depending on how you're code is calling the wrapper method.)
  • 将缓存机制更改为字典、t>和使用serviceCall作为实际的缓存键。(这可能不能工作,这取决于您的代码是如何调用包装器方法的。)

#1


2  

MSDN, referring to the MethodHandle property, says "this property is for access to managed classes from unmanaged code and should not be called from managed code."

MSDN引用MethodHandle属性,表示“此属性用于从非托管代码访问托管类,不应从托管代码调用。”

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

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

Suggestions:

建议:

  • Use serviceCall.Method.MethodHandle anyway since it is supposed to be unique within the same AppDomain.
  • 使用serviceCall.Method。MethodHandle,因为它应该在同一个AppDomain中是唯一的。
  • Research serviceCall.Method.GetHashCode() to see if this would work for you as your caching key.
  • 研究servicecall.method.method.gethashcode(),看看它是否适合作为您的缓存键。
  • Change your caching mechanism to be a Dictionary, T> and use serviceCall as the actual caching key. (This may not work depending on how you're code is calling the wrapper method.)
  • 将缓存机制更改为字典、t>和使用serviceCall作为实际的缓存键。(这可能不能工作,这取决于您的代码是如何调用包装器方法的。)