简体   繁体   English

从应用程序编程(C#/ Visual C ++)到ASP.NET(C#)的一些问题

[英]Some questions coming from application programming (C#/Visual C++) to ASP.NET (C#)

At the new place I am working, I've been tasking with developing a web-application framework. 在我工作的新地方,我一直在开发一个Web应用程序框架。 I am new (6 months ish) to the ASP.NET framework and things seem pretty straight forward, but I have a few questions that I'd like to ask you ASP professionals. 我是ASP.NET框架的新手(6个月),事情看起来非常简单,但我有几个问题,我想问你ASP专业人士。 I'll note that I am no stranger to C#. 我会注意到我对C#并不陌生。

Long life objects/Caching 长寿命对象/缓存

What is the preferred method to deal with objects that you don't want to re-initialize every time a page is it? 处理每次页面不想重新初始化的对象的首选方法是什么? I noticed that there was a cache manager that can be used, but are there any caveats to using this? 我注意到有一个可以使用的缓存管理器,但使用它有什么警告吗? For example, I might want to cache various things and I was thinking about writing a wrapper around the cache that prefixed cache names so that I could implement different caches using the same underlying .NET cache manager. 例如,我可能想要缓存各种各样的东西,我正在考虑围绕缓存编写一个封装器,它以前缀缓存名称为例,这样我就可以使用相同的底层.NET缓存管理器实现不同的缓存。

1) Are there any design considerations I need to think about the objects that I am want to cache? 1)我是否需要考虑我想要缓存的对象的设计考虑因素?

2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? 2)如果我想在Web应用程序的生命周期中实现一段时间的管理器(显然是线程安全的),是否足以在app_start期间初始化它并在app_end中将其终止? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served. 或者这是不受欢迎的,并且任何管理器都是在所服务页面的构造函数/ init方法中唯一创建的。

3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? 3)如果我在应用程序启动时初始化了一个长期对象,那么当应用程序池被回收时,这可能会受到影响吗? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? 如果它在应用程序端被破坏,它只是被破坏然后再次重新创建的情况? I am fine with this restriction, I just want to get a little clearer :) 我很满意这个限制,我只想更清楚:)

Long Life Threads 长寿线程

I've done a bit of research on this and this question is probably redundant. 我对此做了一些研究,这个问题可能是多余的。 It seems it is not safe to start a worker thread in the ASP.NET environment and instead, use a windows service to do long-running tasks. 在ASP.NET环境中启动工作线程似乎是不安全的,而是使用Windows服务来执行长时间运行的任务。 The latter isn't exactly a problem, the target environments will have the facility to install services, but I just wanted to double check that this was absolutely necessary. 后者不是一个问题,目标环境将具有安装服务的功能,但我只想仔细检查这是绝对必要的。 I understand threads can throw exceptions and die, but I do not understand the reasoning behind prohibiting them. 我理解线程可以抛出异常而死,但我不明白禁止它们的原因。 If .NET provided aa thread framework that encompassed System.Thread, but also provided notifications for when the Application Server was going to recycle the App-Pool, we could actually do something about it rather than just keel over and die at the point we were stopped. 如果.NET提供了一个包含System.Thread的线程框架,但也提供了关于Application Server何时要回收App-Pool的通知,我们实际上可以做一些关于它的事情,而不仅仅是关注并在我们停止。

Are there any solutions to threading in ASP.NET or is it basically "service"? 在ASP.NET中是否有任何线程解决方案,或者它基本上是“服务”?

I am sure I'll have more queries, but this is it for now. 我相信我会有更多的疑问,但现在就是这样。

EDIT: Thankyou for all the responses! 编辑:谢谢你的所有回复!

1) The main thing about caching is understanding the lifetime of the cache, and the effects of caching (particularly large) objects in cache. 1)缓存的主要内容是了解缓存的生命周期,以及缓存中缓存(特别是大)对象的影响。 Consider caching a 1MB object in memory that is generated each time your default.aspx page is hit; 考虑在每次访问default.aspx页面时生成的内存中缓存1MB对象; and after a year of production you're getting 10,000 hits an hour, and object lifetime is 2 hours. 经过一年的生产,你每小时获得10,000次点击,物体寿命为2小时。 You can easily chew up TONS of memory, which can affect performance, and also may cause things to be prematurely expired from the cache, which in turn can cause other issues. 您可以轻松地咀嚼内存,这可能会影响性能,也可能导致事件过早地从缓存过期,从而导致其他问题。 As long as you understand the effects of all of this, you're fine. 只要你了解所有这些的影响,你就没事了。

2) Starting it up in Application_Start and shutting it down in Application_End is fine. 2)在Application_Start中启动它并在Application_End中将其关闭就可以了。 You can also implement a custom HttpApplication with an http module. 您还可以使用http模块实现自定义HttpApplication。

3) Yes, when your app pool is recycled it calls Application_End and everything is shutdown and destroyed. 3)是的,当你的应用程序池被回收时,它调用Application_End,一切都被关闭并销毁。

4) (Threads) The issue with threads comes up in relation to scaling. 4)(线程)线程的问题与缩放有关。 If you hit that default.aspx page, and it fires up a thread, and that page gets hit 10,000 in 2 minutes, you could potentially have a ton of threads running in your application pool. 如果你点击default.aspx页面,它会激活一个线程,并且该页面在2分钟内达到10,000,你可能会在你的应用程序池中运行大量的线程。 Again, as long as you understand the ramifications of firing up a thread, you can do it. 同样,只要您了解启动线程的后果,您就可以做到。 ThreadPool is another story, the asp.net runtime uses the ThreadPool to process requests, so if you tie up all the threadpool threads, your application can potentially hang because there isn't a thread available to process the request. ThreadPool是另一个故事,asp.net运行时使用ThreadPool来处理请求,因此如果你占用所有线程池线程,你的应用程序可能会挂起,因为没有可用于处理请求的线程。

So here's the main thing that you're going to want to keep in mind. 所以这是你要记住的主要内容。 The IIS may get reset or may reset itself (based on criteria) while you're working. 在您工作时,IIS可能会重置或自行重置(基于标准)。 You can never know when that will happen unless it stops rendering your page while you're waiting on the response (in which case you'll get a browser notice that the page stopped responding, eventually. 除非在等待响应时停止呈现页面,否则您永远不会知道何时会发生这种情况(在这种情况下,您将获得浏览器通知页面停止响应,最终。

Threads 主题

This is why you shouldn't use threads in ASP.NET apps. 这就是您不应该在ASP.NET应用程序中使用线程的原因。 However, that's not to say you can't. 但是,这并不是说你不能。 Once again, you'll need to configure the IIS engine properly (I've had it hang when spawning a lot of threads, but that may have been machine dependent). 再一次,你需要正确配置IIS引擎(我在生成大量线程时已经将它挂起,但这可能与机器有关)。 If you can trust that nobody will cause ASP.NET to recompile your code/restart your application (by saving the web.config , for instance) then you will have less issues than you might otherwise. 如果您可以相信没有人会让ASP.NET重新编译您的代码/重新启动您的应用程序(例如,通过保存 web.config ),那么您将遇到的问题比您可能没有的那么少。

Instead of running a Windows service, you could use an ASMX or WCF service which also run on IIS/.NET. 您可以使用也在IIS / .NET上运行的ASMX或WCF服务,而不是运行Windows服务。 That's up to you. 随你(由你决定。 But with multiple service pools it allows you to keep everything "in the same environment" as far as installations and builds are concerned. 但是对于多个服务池,它允许您在安装和构建方面保持“在相同环境中”的所有内容。 They obviously don't share the same processpool/memoryspace. 他们显然不共享相同的processpool / memoryspace。

"You're Wrong!" “你错了!”

I'm sure someone will read this far and go "but you can't thread in ASP.NET!!!" 我相信有人会读到这个并且去“但是你无法在ASP.NET中进行操作!!!” so here's the link that shows you how to do it from that venerable MSDN http://msdn.microsoft.com/en-us/magazine/cc164128.aspx 所以这里的链接向您展示如何从古老的MSDN中进行操作http://msdn.microsoft.com/en-us/magazine/cc164128.aspx

Now onto Long life objects/Caching 现在进入Long life对象/缓存

Caching 高速缓存

So it depends on what you mean by caching. 所以它取决于缓存的含义。 Is this per user, per system, per application, per database, or per page? 这是每个用户,每个系统,每个应用程序,每个数据库还是每页? Each is possible, but takes some contrivance and complexity, depending on needs. 每种都是可能的,但根据需要需要一些设计和复杂性。

The simplest way to do it per page is with static variables. 每页最简单的方法是使用静态变量。 This is also highly dangerous if you're using it for user-code-stuff because there's no indication to the end user that the variable is going to change, if more than one users uses the page. 如果您将其用于用户代码内容,这也是非常危险的,因为如果有多个用户使用该页面,则无法向最终用户表明该变量将会发生变化。 Instead, if you need something to live with the user while they work with the page in particular, you could either stuff it into session (serverside caching, stays with the user, they can use it across multiple pages) or you could stick it into ViewState. 相反,如果你需要某些东西与用户一起生活,特别是你可以将它填入会话(服务器端缓存,留在用户,他们可以在多个页面中使用它),或者你可以将它插入到ViewState中。

The cachemanager you reference above would be good for application style caching, where everyone using the webapp can use the same datastore. 您在上面引用的缓存管理器适用于应用程序样式缓存,其中使用webapp的每个人都可以使用相同的数据存储。 That might be good for intensive queries where you want to get the values back as quickly as possible so long as they're not stale. 对于您希望尽快恢复值的密集查询,这可能是有益的,只要它们不是陈旧的。 That's up to you to decide. 这取决于你自己决定。 Also, things like application settings could be stored there, if you use a database layer for storage. 此外,如果您使用数据库层进行存储,那么应用程序设置等内容也可以存储在那里。

Long term cache objects 长期缓存对象

You could initialize it in the app_start with no problem, and the same goes for destroying it at the end if you felt the need, but yes, you do need to watch out for what I described at first about the system throwing all your code out and restarting. 您可以在app_start中初始化它没有任何问题,如果您觉得有必要,也可以在最后销毁它,但是,您需要注意我最初描述的关于系统抛出所有代码的内容并重新启动。

Keel over and die 龙骨过度死亡

But you don't get notified when you're (the app pool here) going to be restarted (as far as I know) so you can pretty much keel over and die on anything. 但是当你(这里的应用程序池)重新启动时(据我所知),你不会得到通知,所以你可以在任何事情上喋喋不休。 Always assume the app is going to go down on you before your request, and that every request is the first one. 始终假设应用程序会在您请求之前拒绝您,并且每个请求都是第一个请求。

Really tho, that just leads back into web-design in the first place. 真的,这只是首先回到网页设计。 You don't know that this is the first visitor or the fifty millionth (unless you're storing that information in memory of course) so just like the app is stateless, you also need to plan your architecture to be stateless as much as possible. 您不知道这是第一个访问者还是第五个百万分之一(除非您当然将这些信息存储在内存中)所以就像应用程序是无状态的一样,您还需要将您的体系结构规划为尽可能无状态。 That's where web-apps are great. 这就是网络应用程序很棒的地方。

If you need state on a regular basis, consider sticking with desktop apps. 如果您需要定期报告状态,请考虑坚持使用桌面应用。 If you can live with stateless-ness, welcome to ASP.NET and web development. 如果您可以忍受无状态,欢迎使用ASP.NET和Web开发。

1) Are there any design considerations I need to think about the objects that I am want to cache? 1)我是否需要考虑我想要缓存的对象的设计考虑因素?

2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? 2)如果我想在Web应用程序的生命周期中实现一段时间的管理器(显然是线程安全的),是否足以在app_start期间初始化它并在app_end中将其终止? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served. 或者这是不受欢迎的,并且任何管理器都是在所服务页面的构造函数/ init方法中唯一创建的。

There's a difference between data caching and output caching. 数据缓存和输出缓存之间存在差异。 I think you're looking for data caching which means caching some object for use in the application. 我认为你正在寻找数据缓存,这意味着缓存一些对象以便在应用程序中使用。 This can be done via HttpContext.Current.Cache. 这可以通过HttpContext.Current.Cache完成。 You can also cache page output and differentiate that on conditions so the page logic doesn't have to run at all. 您还可以缓存页面输出并在条件上区分它,以便页面逻辑根本不必运行。 This functionality is also built into ASP.NET. 此功能也内置于ASP.NET中。 Something to keep in mind when doing data caching is that you need to be careful about the scope of the things you cache. 在进行数据缓存时要记住的一点是,您需要注意缓存的内容的范围。 For example, when using Entity Framework, you might be tempted to cache some object that's been retrieved from the DB. 例如,在使用Entity Framework时,您可能想要缓存从DB检索到的某个对象。 However, if your DB Context is scoped per request (a new one for every user visiting your site, probably the correct way) then your cached object will rely on this DB Context for lazy loading but the DB Context will be disposed of after the first request ends. 但是,如果您的数据库上下文是每个请求的范围(对于访问您站点的每个用户来说都是一个新的,可能是正确的方法),那么您的缓存对象将依赖此DB上下文进行延迟加载,但是DB Context将在第一个之后被处理掉请求结束。

3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? 3)如果我在应用程序启动时初始化了一个长期对象,那么当应用程序池被回收时,这可能会受到影响吗? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? 如果它在应用程序端被破坏,它只是被破坏然后再次重新创建的情况? I am fine with this restriction, I just want to get a little clearer :) 我很满意这个限制,我只想更清楚:)

Perhaps the biggest issue with threading in ASP.NET is that it runs in the same process as all your requests. 在ASP.NET中使用线程的最大问题可能是它在与您的所有请求相同的进程中运行。 Even if this weren't an issue in and of itself, IIS can be configured (and if you don't own the servers almost certainly will be configured) to shut down the app if it's inactive (which you mentioned) which can cause issues for these threads. 即使这本身不是问题,也可以配置IIS(如果您不拥有服务器,几乎肯定会配置),关闭应用程序,如果它处于非活动状态(您提到)可能会导致问题对于这些线程。 I have seen solutions to that including making sure IIS never recycles the app pool to spawning a thread that hits the site to keep it alive even on hosted servers 我已经看到了解决方案,包括确保IIS永远不会回收应用程序池,以产生一个线程,即使在托管服务器上也可以使网站保持活动状态

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM