ProtectedSessionStore多次读写致Razor页面加载缓慢,求优化方案
问题描述
登录网站时,我通过以下代码设置13个会话参数:
ProtectedSessionStore.SetAsync("iduser", iduser); ProtectedSessionStore.SetAsync("unitid", unitid); ProtectedSessionStore.SetAsync("branchid", branchid); ProtectedSessionStore.SetAsync("organid", organid); ProtectedSessionStore.SetAsync("defuser", defuser); ProtectedSessionStore.SetAsync("defbranch", defbranch); ProtectedSessionStore.SetAsync("defunit", defunit); ProtectedSessionStore.SetAsync("defproduct", defproduct); ProtectedSessionStore.SetAsync("defpointofbody", defpointofbody); ProtectedSessionStore.SetAsync("defdegree", defdegree); ProtectedSessionStore.SetAsync("defvisit", defvisit); ProtectedSessionStore.SetAsync("defpatient", defpatient); ProtectedSessionStore.SetAsync("report", report);
登录后,我需要在NavMenu布局页和MainMenu页这两个Razor页面中获取这些值,所以在两个页面里都用了以下代码:
var result = await ProtectedSessionStore.GetAsync<int>("iduser"); iduser = result.Success ? result.Value : 0; result = await ProtectedSessionStore.GetAsync<int>("unitid"); unitid = result.Success ? result.Value : 0; result = await ProtectedSessionStore.GetAsync<int>("branchid"); branchid = result.Success ? result.Value : 0; result = await ProtectedSessionStore.GetAsync<int>("organid"); organid = result.Success ? result.Value : 0; var result1 = await ProtectedSessionStore.GetAsync<bool>("defuser"); defuser = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defbranch"); defbranch = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defunit"); defunit = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defvisit"); defvisit = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defdegree"); defdegree = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defpointofbody"); defpointofbody = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defpatient"); defpatient = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("defproduct"); defproduct = result1.Success ? result1.Value : false; result1 = await ProtectedSessionStore.GetAsync<bool>("report"); report = result1.Success ? result1.Value : false;
现在的问题是加载这些参数的速度非常慢,请问如何加速该过程?
优化方案
1. 将多个参数封装为单个对象存储/读取
把所有会话参数打包成一个自定义类,仅需一次SetAsync和GetAsync操作,大幅减少IO交互次数:
步骤1:定义会话参数类
public class SessionUserInfo { public int IdUser { get; set; } public int UnitId { get; set; } public int BranchId { get; set; } public int OrganId { get; set; } public bool DefUser { get; set; } public bool DefBranch { get; set; } public bool DefUnit { get; set; } public bool DefProduct { get; set; } public bool DefPointOfBody { get; set; } public bool DefDegree { get; set; } public bool DefVisit { get; set; } public bool DefPatient { get; set; } public bool Report { get; set; } }
步骤2:登录时一次性存储
var sessionInfo = new SessionUserInfo { IdUser = iduser, UnitId = unitid, BranchId = branchid, OrganId = organid, DefUser = defuser, DefBranch = defbranch, DefUnit = defunit, DefProduct = defproduct, DefPointOfBody = defpointofbody, DefDegree = defdegree, DefVisit = defvisit, DefPatient = defpatient, Report = report }; await ProtectedSessionStore.SetAsync("UserSessionInfo", sessionInfo);
步骤3:页面中一次性读取
var result = await ProtectedSessionStore.GetAsync<SessionUserInfo>("UserSessionInfo"); var sessionInfo = result.Success ? result.Value : new SessionUserInfo(); // 直接使用对象属性即可 var iduser = sessionInfo.IdUser; var defuser = sessionInfo.DefUser; // ...其他参数同理
2. 异步并行读取(临时方案)
如果暂时不想修改存储方式,可通过Task.WhenAll并行发起所有读取请求,减少串行等待时间:
// 并行发起所有Get请求 var iduserTask = ProtectedSessionStore.GetAsync<int>("iduser"); var unitidTask = ProtectedSessionStore.GetAsync<int>("unitid"); var branchidTask = ProtectedSessionStore.GetAsync<int>("branchid"); var organidTask = ProtectedSessionStore.GetAsync<int>("organid"); var defuserTask = ProtectedSessionStore.GetAsync<bool>("defuser"); var defbranchTask = ProtectedSessionStore.GetAsync<bool>("defbranch"); var defunitTask = ProtectedSessionStore.GetAsync<bool>("defunit"); var defproductTask = ProtectedSessionStore.GetAsync<bool>("defproduct"); var defpointofbodyTask = ProtectedSessionStore.GetAsync<bool>("defpointofbody"); var defdegreeTask = ProtectedSessionStore.GetAsync<bool>("defdegree"); var defvisitTask = ProtectedSessionStore.GetAsync<bool>("defvisit"); var defpatientTask = ProtectedSessionStore.GetAsync<bool>("defpatient"); var reportTask = ProtectedSessionStore.GetAsync<bool>("report"); // 等待所有任务完成 await Task.WhenAll(iduserTask, unitidTask, branchidTask, organidTask, defuserTask, defbranchTask, defunitTask, defproductTask, defpointofbodyTask, defdegreeTask, defvisitTask, defpatientTask, reportTask); // 处理结果 iduser = iduserTask.Result.Success ? iduserTask.Result.Value : 0; unitid = unitidTask.Result.Success ? unitidTask.Result.Value : 0; branchid = branchidTask.Result.Success ? branchidTask.Result.Value : 0; organid = organidTask.Result.Success ? organidTask.Result.Value : 0; defuser = defuserTask.Result.Success ? defuserTask.Result.Value : false; defbranch = defbranchTask.Result.Success ? defbranchTask.Result.Value : false; defunit = defunitTask.Result.Success ? defunitTask.Result.Value : false; defproduct = defproductTask.Result.Success ? defproductTask.Result.Value : false; defpointofbody = defpointofbodyTask.Result.Success ? defpointofbodyTask.Result.Value : false; defdegree = defdegreeTask.Result.Success ? defdegreeTask.Result.Value : false; defvisit = defvisitTask.Result.Success ? defvisitTask.Result.Value : false; defpatient = defpatientTask.Result.Success ? defpatientTask.Result.Value : false; report = reportTask.Result.Success ? reportTask.Result.Value : false;
3. 缓存读取结果(针对重复读取场景)
NavMenu和MainMenu属于高频访问页面,可将读取到的会话参数缓存到HttpContext.Items中,同一个请求内仅读取一次:
// 示例:在NavMenu的OnGetAsync方法中 if (!HttpContext.Items.ContainsKey("UserSessionInfo")) { var result = await ProtectedSessionStore.GetAsync<SessionUserInfo>("UserSessionInfo"); HttpContext.Items["UserSessionInfo"] = result.Success ? result.Value : new SessionUserInfo(); } // 后续页面直接从缓存获取 var sessionInfo = (SessionUserInfo)HttpContext.Items["UserSessionInfo"];
4. 检查底层存储配置
如果使用Cookie作为存储载体,确保加密配置高效,避免冗余计算;如果是分布式存储(如Redis),检查网络连接和节点性能,降低读写延迟。
内容的提问来源于stack exchange,提问作者Kasra Ghavami
相关产品推荐
相关产品推荐

