【问题标题】:How to display the content of asp.net cache?如何显示asp.net缓存的内容?
【发布时间】:2011-08-18 13:46:45
【问题描述】:

我们有一个使用 HttpRuntime.Cache 的 asp.net MVC Web 应用程序
对象以保留一些静态查找值。我们希望能够监控什么是
实时缓存,以便我们查明一些可能的缓存问题。

由于这个对象在读取时不是强类型的,我们需要动态地
将每个条目转换为它的具体类型。

大多数缓存项都是 IEnumerable 的,其中 T 可以是我们在我们的
中使用的任何类 随着项目的进一步推进,最终可能会添加新项目或新项目。
有人可以告诉我如何做到这一点吗?

非常感谢。

【问题讨论】:

  • 您认为可能是什么问题?它可以帮助提供有关如何监控它的建议,而不是这种潜在的大锤方法。
  • 它用于检测“可能”发生的问题,因此我们无法提前知道。

标签: c# caching reflection dynamic casting


【解决方案1】:

您可以尝试使用 JavaScriptSerializer 类对其进行 Json 序列化。这样您就不需要转换为原始类型,因为 Serialize 方法可以获取任何对象并以人类可读的 JSON 格式输出。它可能会阻塞某些复杂类型,如果发生这种情况,您也可以尝试Newtonsoft Json.NET

【讨论】:

  • 有趣!但是我在弄清楚如何使用它来实现我们需要的东西时遇到了问题。你能详细说明一下吗?
  • @Stéphan,像这样:string result = new JavaScriptSerializer().Serialize(someObjectInstance); someObjectInstance 可以是任何东西。所以你可以遍历缓存中的值并像这样序列化它们。
  • 我怀疑,缓存中的对象图相当大,我收到一条消息:使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了 maxJsonLength 属性上设置的值。我试图设置我的序列化程序的 MaxJsonLength 属性。
【解决方案2】:

使用 ASP.NET MVC 本身。

public ActionResult Index()
{
    return View(HttpRuntime.Cache)
}

为了风景

Html.DisplayForModel()

您将需要使用自定义对象模板(基本上采用 MVC 模板并关闭深度限制)。

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html

在您要更改的对象模板上

else if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
    <%= ViewData.ModelMetadata.SimpleDisplayText %>

然后将 > 1 更改为更大的数字,例如 5-10,或者完全删除此深度检查(我可能会从 5 开始,然后从那里开始)。

【讨论】:

  • 这似乎是最好的方法,但是,您能详细说明一下您建议我如何做吗?我的意思是,关于模板,我需要做什么才能让这一切顺利进行?
  • 您需要在 Views
  • 但是这个模板将如何确定如何显示缓存中的信息存储?我的意思是,因为它是一个对象类型,在模板中,我不能访问任何属性,此外,因为它可以是任何东西,我怎么能做这样的事情而不必为每个类型代码编写特定的类型转换?
  • 这就是我的意思,如果您直接使用该对象模板并增加或关闭深度,您不需要做任何工作 PERIOD。您将利用 MVC 模型绑定将 Cache 包分解为树结构中的 100 或 1000 个属性,每个属性最终都会归结为字符串、int 等基本类型,显示时没有问题。 MVC 模型绑定将为您遍历对象图。
  • 我现在明白了!实际上很简单,我只是对自定义模板有一些误解。现在,它就像一个魅力,完全符合我们的需要!非常感谢!!!!
【解决方案3】:

重要的是要强调缓存存在于 MVC Web 应用的应用域中,因此无法从外部访问,您需要实现一些应用内监控或应用域间通信以启用外部应用程序从您的 MVC 应用程序域请求缓存数据。

【讨论】:

  • 是的,为了记录,我们的缓存管理器将在同一个网络应用程序中,所以这不是问题,但感谢您为可能知道这一点的其他人澄清它。 :)
【解决方案4】:

好吧,我认为您要求的是一种在运行时确定泛型类型的类型参数的方法 - 在您的示例中,情况很复杂,因为您所追求的接口不是一个对象实例。

尽管如此,这仍然非常简单,以下示例至少应该为您指明正确的方向:

object obj= new List<string>();
Type type = obj.GetType();

Type enumerable = type.GetInterfaces().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
if (enumerable != null)
{
    Type listType = enumerable.GetGenericArguments()[0];
    if (listType == typeof(string))
    {
        IEnumerable<string> e = obj as IEnumerable<string>;
    }
}

但我真的看不出这如何帮助您解决监控缓存的潜在问题?

过去,在尝试监控缓存的性能时,我发现创建自己的简单 Perfmon 计数器对监控目的非常有帮助 - 作为一个基本示例,从“# Entries”计数器开始(每当一个项目被添加到缓存中并在从缓存中删除项目时递减),并添加您认为有用的计数器 - 缓存命中计数器和缓存未命中计数器通常也非常有用。

您还可以让您的 Perfmon 计数器通过拥有许多计数器实例来分解缓存信息,每种类型都缓存一个(或者在您的情况下更可能是通用 IEnumerable 类型被缓存) - 就像“进程" perfmon 计数器组为系统上的每个进程都有一个实例,缓存中的每种类型都有一个实例(另外,您还应该添加一个“_Total”实例或类似实例)。

通过记录缓存上的操作来使用 Perfmon 计数器,您可以非常详细地监控缓存性能,而运行时性能开销很小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-15
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 2013-06-15
    相关资源
    最近更新 更多