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

标签 c# .net caching reflection methodinfo

在 WCF 客户端应用程序中,有许多我们希望为其缓存结果的无参数方法 - GetAllFoo()GetAllBar()。这些用于填充下拉菜单等,结果在客户端的运行期间不会改变。

这些结果当前由存储在资源文件中的唯一字符串缓存 - 例如,GetAllCountries() 缓存在 CountryKey 资源中。仅当缓存不包含请求的 key 时才会调用该服务。

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 委托(delegate)有一个Method 属性,它描述了要执行的方法。这是一个 MethodInfo 实例,它又包含一个 MethodHandle 属性。我假设 MethodHandle 属性唯一且一致地标识所引用的方法是否正确?

我会将包装器更改为

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

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

  • 不关心 MethodHandle 是否在实例之间发生变化 - 缓存仅针对每个实例
  • 不关心 MethodHandle 是否跨客户端不一致 - 缓存是每个客户端
  • DO 关心客户端实例中的 MethodHandle 是否不一致 - 我实际上希望使用缓存,而不是每个请求都会导致新的服务调用并且缓存充满未使用的数据
  • 务必注意客户端实例中的 MethodHandle 是否唯一 - 我必须确保在使用包装器时返回正确的数据(和类型)。

最佳答案

MSDN 在提及 MethodHandle 属性时说“此属性用于从非托管代码访问托管类,不应从托管代码调用。”

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

建议:

  • 无论如何都要使用 serviceCall.Method.MethodHandle,因为它在同一个 AppDomain 中应该是唯一的。
  • 研究 serviceCall.Method.GetHashCode() 以查看这是否适合您作为缓存键。
  • 将缓存机制更改为字典,T> 并使用 serviceCall 作为实际缓存键。 (这可能不起作用,具体取决于您的代码调用包装器方法的方式。)

关于c# - 使用方法的 MethodHandle 作为键来缓存无参数方法的结果是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5189518/

相关文章:

css - Plone 发送一个指向已缓存但为空的 ploneCustom.css 的链接

c# - 解析以分号分隔的列表

c# - 检查客户端是否正在尝试连接?

c# - 如何包含行号和文件名 Console.WriteLine 输出?

c# - 检索 MS Access 文件中的表列表

php - 通过 URL 缓存是一种好习惯吗?

c# - 如何将表达式传递到 LINQ 查询中?

c# - 为单个字符/字形 (OCR) 实现模板匹配

c# - 在应用程序和 IFrame 之间传递凭据

javascript - 缓存主干 View 及其事件