【问题标题】:c# .net in-memory persistencec# .net 内存中持久性
【发布时间】:2012-10-09 14:40:03
【问题描述】:

我想为服务器发回的每个请求提供一条“用户消息”。如果没有用户消息,则消息返回空白。如果有,则在每个用户屏幕上在他们的请求完成后激活一个图标。

[编辑] “用户消息”是管理员为我正在部署的应用程序设置的内容。管理员可以在字段中输入文本并单击按钮以将此消息发送给系统的所有其他用户。每当其他用户执行任何类型的操作时,当前用户消息都会附加到 JSON 响应并由前端处理。

为了优化这一点,我希望将消息存储在内存中(而不是在数据库中)。

我尝试过使用静态。我曾尝试使用 HttpApplicationState。在这两种情况下,用户消息的值都会在一段时间后“消失”。经过一些研究,似乎静态和 HttpApplicationState 都受 IIS 的影响,并且当它决定回收应用程序池时。 (或类似的)

static 的这种波动性是神秘的:它应该是 static - 只要 IIS 本身存在,这个变量就应该存在。它不应该依赖于某种“重置”或其他任何东西。 HttpApplicationState 是我不完全理解的其他情况。

我想要一种将值存储在我可以依赖的非易失性变量中的方法。如果我今天设置此值,它应该在明天或下周出现,只要 IIS 没有停止并重新启动。

有什么帮助吗?


这是我根据以下接受的答案解决问题的方法:

  1. 用户消息有时会发生。因此,当某个管理员设置消息时,将响应存储在该时间点的数据库中,并将其存储在 Application["UserMessage"] 对象中。
  2. 当用户往返时,用户消息的内存文本被添加到 json 返回值中。
  3. 管理员可以随时清除消息,这会清除内存中的消息和数据库字段。
  4. 当 IIS 确定足够了并回收应用程序时,Application_Start() 方法(以及其他任务)还将从设置用户消息时存储的数据库值中重新播种用户消息(按照步骤 1 )。

现在应用程序按预期工作。对于每个进入系统的用户请求,无需为进入数据库支付额外的费用 - 用户消息始终来自内存。除此之外,数据库为用户消息更新或加载的次数很少。

【问题讨论】:

  • 看我的回答,如果变量从内存中销毁,你可以使用 application_start 来恢复它。这只发生在 IIS 回收您的应用程序时。
  • 感谢 kabul,我已根据您的回复更新了原始问题以澄清我的要求。对不起,泥泞..
  • 您可以随时将消息放入应用程序缓存和数据库中。当管理员第一次发送消息时,您需要做的就是将它放入数据库以及应用程序缓存中。您的代码将始终从应用程序缓存中发送消息,但由于应用程序重新启动后应用程序缓存将失效,您需要在 application_start 上从数据库中重新加载它。
  • 我知道关于这个确切的主题有很多问题。这是一个相当不错的解决方案,希望能帮助遇到同样问题的其他人。

标签: static non-volatile httpapplicationstate


【解决方案1】:

应用程序缓存是它的好地方。你的问题是,你认为你不能依赖它。请参阅我的答案的后面部分,您将在其中找到如何确保该值始终存在,即使在 iis 重新启动或 iis 回收您的应用程序之后也是如此。

您可以将值存储在应用程序缓存中。可以这样做

Application.Add(name,object)

稍后您可以使用此代码在每个请求中检索它

Application[name]

它像会话一样工作,但唯一的区别是它是应用程序范围的,所有用户的所有请求都会得到它。当您第一次分配设置值时,将其存储在 db 以及应用程序缓存中,以便您以后可以从 db 进行查询并将其存储在应用程序缓存中,如果值不存在,然后从应用程序缓存中检索它。

您应该在每次应用程序启动或重新启动时触发的Application_Start() 事件从数据库中恢复应用程序缓存。这样可以确保它始终在应用程序缓存中。

【讨论】:

  • 但此解决方案要求 application_start() 知道启动时的值是什么。这个值是任意的。我在原始帖子中并不完全清楚,因此我对其进行了编辑以澄清。
  • 此时是否要输入值由您决定。您能否澄清一下您所说的任意是什么意思?在某个时间点,您必须知道将其存储在某处的值。
  • 任意,我的意思是任意。有人坐在应用程序旁,键入一个值,该值以某种方式存储在服务器上——希望在内存中。该值不是在 application_start() 中预先确定的,而是在该时间点之后的某个时间动态生成的。请参阅下面的答案,了解我如何同时使用持久性和应用程序对象来解决问题。
  • 感谢您更新您的答案。我已将其标记为正确答案。希望我的其他回复会消失。
【解决方案2】:

我想要一种将值存储在我自己的非易失性变量中的方法 可以依靠。如果我今天设置这个值,它明天应该在那里, 或者下周,只要 IIS 没有停止并重新启动。

在这种情况下,您不能将此值存储在内存中。内存是 IIS 分配给您的,用于托管应用程序的 AppDomain。 IIS 可以随时回收您的应用程序并清除内存。虽然 IIS 继续存在,但您的应用程序却没有。所以你不能依赖它。在这种情况下,唯一可靠的解决方案是将此信息保存在一些非易失性存储中,例如文件、数据库……选择权完全取决于您,但它应该不在您的 AppDomain 进程中。

【讨论】:

  • 后续问题:有没有办法知道iis即将回收我的应用程序?我不想为此发疯,但这是我不想用 .. 打击数据库的东西。
  • 不,没有办法。 IIS 可以随时回收您的应用程序。例如,如果您的应用程序达到某些 CPU 或内存使用阈值。唯一可靠的解决方案是进程外持久性。
猜你喜欢
  • 2011-02-27
  • 2023-03-14
  • 2011-04-12
  • 2012-03-08
  • 2011-01-23
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多