代码之家  ›  专栏  ›  技术社区  ›  Moo-Juice

从应用编程(C/VisualC++)到ASP.NET(C)的几个问题

  •  4
  • Moo-Juice  · 技术社区  · 14 年前

    在我工作的新地方,我一直在负责开发一个Web应用程序框架。我是ASP.NET框架的新手(6个月左右),事情看起来非常直接,但我有几个问题想问您ASP专业人员。我会注意到我对C并不陌生。

    长寿命对象/缓存

    处理不希望每次页面都重新初始化的对象的首选方法是什么?我注意到有一个缓存管理器可以使用,但是使用它有什么注意事项吗?例如,我可能想要缓存各种各样的东西,我正在考虑在缓存周围写一个包装器,它为缓存名加前缀,这样我就可以使用相同的底层.NET缓存管理器实现不同的缓存。

    1)对于要缓存的对象,是否需要考虑任何设计考虑?

    2)如果我想在Web应用程序的生命周期中实现一个时间管理器(显然是线程安全的),那么在应用程序启动和在应用程序结束时初始化它是否足够?或者,这种做法不受欢迎,并且任何管理器都是在所服务页面的constructor/init方法中唯一创建的。

    3)如果我有一个在应用程序启动时初始化的长期对象,当应用程序池被回收时,这可能会受到影响吗?如果它在应用程序端被销毁,它是一个简单的被销毁然后重新创建的情况吗?我可以接受这个限制,我只是想更清楚一点:)

    长寿命螺纹

    我对此做了一些研究,这个问题可能是多余的。在ASP.NET环境中启动工作线程似乎不安全,而是使用Windows服务来执行长时间运行的任务。后者并不完全是问题,目标环境将具有安装服务的功能,但我只是想再次检查这是否绝对必要。我知道线程可以抛出异常并导致死亡,但我不理解禁止它们背后的原因。如果.NET提供了一个包含system.thread的线程框架,但也提供了应用服务器何时要回收应用程序池的通知,那么我们实际上可以对它做些什么,而不仅仅是在我们停止的时候死掉。

    ASP.NET中是否有线程解决方案,或者基本上是“服务”?

    我相信我会有更多的疑问,但现在就到此为止。

    编辑:感谢您的所有回复!

    3 回复  |  直到 14 年前
        1
  •  3
  •   jcolebrand    14 年前

    这是你要记住的主要事情。在您工作时,IIS可能会被重置,也可能会自行重置(根据条件)。除非它在等待响应时停止呈现您的页面,否则您永远无法知道何时会发生这种情况(在这种情况下,您将收到浏览器通知,页面最终停止响应)。

    螺纹

    这就是为什么您不应该在ASP.NET应用程序中使用线程的原因。但是,这并不是说你不能这样做。再一次,你需要正确配置IIS引擎(我在生成大量线程时挂起了它,但这可能与机器有关)。如果您可以相信没有人会导致ASP.NET重新编译代码/重新启动应用程序(通过 节约 这个 web.config 例如),那么您的问题将比其他问题少。

    您可以使用在IIS/.NET上运行的asmx或wcf服务,而不是运行Windows服务。这由你决定。但有了多个服务池,就安装和构建而言,它允许您将所有内容“保存在同一个环境中”。它们显然不共享相同的进程池/内存空间。

    “你错了!”

    我敢肯定有人会读到这篇文章,然后说“但是你不能在ASP.NET中执行线程!!这是一个链接,向您展示了如何从古老的msdn中完成这项工作。 http://msdn.microsoft.com/en-us/magazine/cc164128.aspx

    现在开始 长寿命对象/缓存

    缓存

    所以这取决于你所说的缓存。这是每个用户、每个系统、每个应用程序、每个数据库还是每页?每一个都是可能的,但需要一些发明和复杂性,这取决于需要。

    每页最简单的方法是使用静态变量。如果您将它用于用户代码方面,这也是非常危险的,因为如果有多个用户使用该页面,则不会向最终用户指示变量将要更改。相反,如果在用户处理页面时需要与他们一起生活,那么您可以将其放入会话(服务器端缓存,保留在用户身边,他们可以跨多个页面使用它),或者将其保持在视图状态。

    上面引用的cachemanager对于应用程序样式的缓存很好,在这种情况下,使用webapp的每个人都可以使用相同的数据存储。如果您希望在不过时的情况下尽可能快地返回值,那么这对于密集的查询可能是很好的。这由你决定。此外,如果使用数据库层进行存储,那么应用程序设置等内容也可以存储在那里。

    长期缓存对象

    你可以在应用程序中初始化它,从没有问题开始,如果你觉得有必要,也可以在最后销毁它,但是的,你确实需要注意我最初描述的关于系统抛出所有代码并重新启动的内容。

    龙骨上模

    但是当你(这里的应用程序池)要重新启动(据我所知)时,你不会得到通知,所以你可以在任何事情上都死气沉沉。始终假设应用程序会在你的请求之前就向你发出请求,并且每个请求都是第一个请求。

    真的,那只是一开始就回到了网页设计。您不知道这是第一个访问者或第五千万个访问者(当然,除非您将这些信息存储在内存中),所以就像应用程序是无状态的一样,您还需要尽可能地将架构规划为无状态的。这就是网络应用的伟大之处。

    如果你经常需要状态,考虑使用桌面应用。如果您可以忍受无状态性,欢迎使用ASP.NET和Web开发。

        2
  •  3
  •   CodingGorilla    14 年前

    1)缓存的主要内容是了解缓存的生存期,以及缓存(特别是大型)对象在缓存中的效果。考虑在内存中缓存一个1MB对象,该对象在每次点击default.aspx页面时都会生成;在生产一年后,每小时点击10000次,对象生存期为2小时。您可以轻松地咀嚼大量的内存,这会影响性能,也可能导致缓存中的内容过早过期,从而导致其他问题。只要你了解所有这些的影响,你就没事了。

    2)应用程序启动和应用程序关闭都可以。您还可以使用HTTP模块实现自定义http应用程序。

    3)是的,当你的应用程序池被回收时,它会调用应用程序\结束,所有东西都会被关闭和销毁。

    4)(线程)线程的问题与缩放有关。如果您点击那个default.aspx页面,它会触发一个线程,并且该页面在2分钟内达到10000,那么您的应用程序池中可能会运行大量的线程。再说一次,只要你了解触发线程的后果,你就可以做到。threadpool是另一种情况,ASP.NET运行时使用threadpool来处理请求,因此如果您绑定了所有的threadpool线程,则应用程序可能会挂起,因为没有线程可用于处理请求。

        3
  •  3
  •   hackerhasid    14 年前

    1)对于要缓存的对象,是否需要考虑任何设计考虑?

    2)如果我想在Web应用程序的生命周期中实现一个时间管理器(显然是线程安全的),那么在应用程序启动和在应用程序结束时初始化它是否足够?或者,这种做法不受欢迎,并且任何管理器都是在所服务页面的constructor/init方法中唯一创建的。

    数据缓存和输出缓存有区别。我认为您正在寻找数据缓存,这意味着缓存一些对象以便在应用程序中使用。这可以通过httpcontext.current.cache完成。您还可以缓存页面输出,并在条件下区分这些输出,这样页面逻辑就不必运行。此功能也内置于ASP.NET中。在进行数据缓存时要记住的一点是,您需要注意缓存内容的范围。例如,在使用实体框架时,您可能会尝试缓存一些从数据库中检索到的对象。但是,如果您的数据库上下文是按请求划分的范围(每个访问您的站点的用户都有一个新的范围,可能是正确的方式),那么您的缓存对象将依赖于此数据库上下文进行延迟加载,但在第一个请求结束后,数据库上下文将被释放。

    3)如果我有一个在应用程序启动时初始化的长期对象,当应用程序池被回收时,这可能会受到影响吗?如果它在应用程序端被销毁,它是一个简单的被销毁然后重新创建的情况吗?我可以接受这个限制,我只是想更清楚一点:)

    在ASP.NET中,线程的最大问题可能是它与所有请求在同一进程中运行。即使这本身并不是一个问题,也可以配置IIS(如果您不拥有服务器,几乎可以肯定会配置)在应用程序处于非活动状态(您提到过)时关闭它,这会导致这些线程出现问题。我已经看到了解决方案,包括确保IIS从不回收应用程序池,以生成一个线程,该线程会访问该站点,使其即使在托管服务器上也能保持活动。