You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 04:14:55