在ASP.NET中构建自定义文件缓存可以显著提升性能,尤其适用于频繁读取的静态文件(如css、JS、图像),以下是完整实现方案,包含LRU淘汰策略、Target="_blank">线程安全和文件监控:
解决方案设计
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.IO;using System.Linq;using System.Threading;public class FileCache{// 缓存项private class CachedFile{public byte[] Content { get; set; }public DateTime LastModified { get; set; }public LinkedListNode LruNode { get; set; }public int Size => Content?.Length ?? 0;}// 核心数据结构private readonly ConcurrentDictionary _cache = new();private readonly LinkedList _lruList = new();private readonly object _lruLock = new();private long _totalSize = 0;// 配置参数public long MaxCacheSize { get; }public TimeSpan FileCheckInterval { get; }public FileCache(long maxCacheSize = 100 * 1024 * 1024, // 默认100MBTimeSpan? fileCheckInterval = null){MaxCacheSize = maxCacheSize;FileCheckInterval = fileCheckInterval ?? TimeSpan.FromMinutes(5);// 启动后台清理线程var cleanupThread = new Thread(CacheMaintenanceLoop) {IsBackground = true,Priority = ThreadPriority.BelowNormal};cleanupThread.Start();}public byte[] GetFile(string filePath){// 1. 尝试从缓存获取if (_cache.TryGetValue(filePath, out var cachedFile)){lock (_lruLock){// 移动至LRU链表头部_lruList.Remove(cachedFile.LruNode);_lruList.AddFirst(cachedFile.LruNode);}return cachedFile.Content;}// 2. 缓存未命中则加载文件var fileInfo = new FileInfo(filePath);if (!fileInfo.Exists) throw new FileNotFoundException();var content = File.ReadallBytes(filePath);var newEntry = new CachedFile {Content = content,LastModified = fileInfo.LastWriteTimeUtc};// 3. 检查文件是否过大if (content.Length > MaxCacheSize * 0.1) // >10% 最大缓存return content; // 跳过缓存直接返回// 4. 添加缓存项lock (_lruLock){// 处理重复添加if (_cache.TryGetValue(filePath, out cachedFile)){_lruList.Remove(cachedFile.LruNode);_lruList.AddFirst(cachedFile.LruNode);return cachedFile.Content;}// 创建新节点var node = new LinkedListNode(filePath);newEntry.LruNode = node;// 添加至缓存if (_cache.TryAdd(filePath, newEntry)){_lruList.AddFirst(node);Interlocked.Add(ref _totalSize, content.Length);EvictIfNeeded();}}return content;}private void EvictIfNeeded(){while (_totalSize > MaxCacheSize && _lruList.Count > 0){string keyToRemove;lock (_lruLock){if (_lruList.Last == null) break;keyToRemove = _lruList.Last.Value;}if (_cache.TryRemove(keyToRemove, out var removed)){lock (_lruLock){_lruList.Remove(removed.LruNode);Interlocked.Add(ref _totalSize, -removed.Size);}}}}private void CacheMaintenanceLoop(){while (true){Thread.Sleep(FileCheckInterval);CheckForModifiedFiles();}}private void CheckForModifiedFiles(){var keys = _cache.Keys.ToList();foreach (var filePath in keys){if (!File.Exists(filePath)){RemoveFromCache(filePath);continue;}var currentWriteTime = File.GetLastWriteTimeUtc(filePath);if (_cache.TryGetValue(filePath, out var cachedFile) &&cachedFile.LastModified != currentWriteTime){RemoveFromCache(filePath);}}}private void RemoveFromCache(string filePath){if (_cache.TryRemove(filePath, out var removed)){lock (_lruLock){_lruList.Remove(removed.LruNode);Interlocked.Add(ref _totalSize, -removed.Size);}}}}
关键优化点说明
使用示例
// 初始化缓存(100MB上限)var cache = new FileCache(100 * 1024 * 1024);// 获取文件(自动缓存)var cssContent = cache.GetFile(@"C:sitestylesmain.css");// 在ASP.NET中输出context.Response.ContentType = "text/css";context.Response.OutputStream.Write(cssContent, 0, cssContent.Length);
性能优化建议
适用场景
此实现相比ASP.NET内置缓存优势:
可根据实际需求扩展缓存过期策略、添加性能计数器或集成到ASP.NET Core的
IFileProvider
体系。
ASP.NET中常用的优化性能方法都有哪些?
个人觉得优点是1.界面和逻辑分离2.编写调试简单,东西很易用。 网上找的观点以前的 Web 开发模型相比, 提供了数个重要的优点:增强的性能。 是在服务器上运行的编译好的公共语言运行库代码。 与被解释的前辈不同, 可利用早期绑定、实时编译、本机优化和盒外缓存服务。 这相当于在编写代码行之前便显著提高了性能。 世界级的工具支持。 框架补充了 Visual Studio 集成开发环境中的大量工具箱和设计器。 WYSIWYG 编辑、拖放服务器控件和自动部署只是这个强大的工具所提供功能中的少数几种。 威力和灵活性。 由于 基于公共语言运行库,因此 Web 应用程序开发人员可以利用整个平台的威力和灵活性。 框架类库、消息处理和数据访问解决方案都可从 Web 无缝访问。 也与语言无关,所以可以选择最适合应用程序的语言,或跨多种语言分割应用程序。 另外,公共语言运行库的交互性保证在迁移到 时保留基于 COM 的开发中的现有投资。 简易性。 使执行常见任务变得容易,从简单的窗体提交和客户端身份验证到部署和站点配置。 例如, 页框架使您可以生成将应用程序逻辑与表示代码清楚分开的用户界面,和在类似 Visual Basic 的简单窗体处理模型中处理事件。 另外,公共语言运行库利用托管代码服务(如自动引用计数和垃圾回收)简化了开发。 可管理性。 采用基于文本的分层配置系统,简化了将设置应用于服务器环境和 Web 应用程序。 由于配置信息是以纯文本形式存储的,因此可以在没有本地管理工具帮助的情况下应用新设置。 此零本地管理哲学也扩展到了 框架应用程序的部署。 只需将必要的文件复制到服务器,即可将 框架应用程序部署到服务器。 不需要重新启动服务器,即使是在部署或替换运行的编译代码时。 可缩放性和可用性。 在设计时考虑了可缩放性,增加了专门用于在聚集环境和多处理器环境中提高性能的功能。 另外,进程受到 运行库的密切监视和管理,以便当进程行为不正常(泄漏、死锁)时,可就地创建新进程,以帮助保持应用程序始终可用于处理请求。 自定义性和扩展性。 随附了一个设计周到的结构,它使开发人员可以在适当的级别插入代码。 实际上,可以用自己编写的自定义组件扩展或替换 运行库的任何子组件。 实现自定义身份验证或状态服务一直没有变得更容易。
ASP网页如何禁用缓存?
在Asp页面首部加入 = = Now() - = = Pragma, No-Cache
ASP.NET中的数据缓存的概念、方式与适用场景是什么?
呃.貌似缓存技术的概念就是原理吧:
系统把访问较频繁的数据及需要大量时间处理的数据存储在内存中.当用户请求这些数据的时候.系统直接把内存中的数据返回给用户.从而提高应用程序的性能..
方式大约有三种:
1.整页缓存
<%OutputCache
Duration=10 //表示页面缓存时间 单位:s
VaryByParam=id;name;....
//表示以参数传递的页面都将被缓存 (none表无变化 * 表根据所有参数变化)
VaryByControl=none
//用来改变用户控件的输出缓存
Location=any //输出缓存位置 默认any
VaryBycustom=browser //自定义输出缓存
适用于不需要频繁更新数据的页面
2.页面部分缓存
先缓存整个页面 再替换页面中不需要缓存的部分
需要用到Substitution控件
适用页面某些部分每次请求都保持最新
3.应用程序缓存
1.指定键值 Cache[key]=value //方便.但不能设置有效期
2.使用add()方法
(key,value,null,(6),
//参数必须完整.不够灵活
3.使用Insert()方法
此方法可实现重载.使用灵活
呃.只知道这么多啦.欢迎补充哈...














发表评论