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

ASP Webform中如何让Ajax调用独立不阻塞后续服务端请求

你遇到的同用户请求排队问题,根本原因是ASP.NET Session的排他锁机制:只要接口开启了Session可写权限,来自同一个会话的所有请求默认会被串行执行,后发起的请求必须等待前一个同会话请求处理完成、释放Session锁之后才会开始执行,和前端Ajax调用本身无关,你当前的前端Ajax配置默认就是异步的,不需要做任何修改。

可落地解决方案

方案1:调整Session访问模式(改动最小,优先尝试)

如果你的接口仅需要读取Session、不需要写入,或者可以拆分读写逻辑,直接把WebMethod的Session权限改为只读即可解除排他锁:
将原方法的特性

[System.Web.Services.WebMethod(EnableSession = true)]

修改为:

[System.Web.Services.WebMethod(EnableSession = System.Web.Services.SessionStateBehavior.ReadOnly)]

注意:只读模式下Session仅支持读取操作,无法写入数据,如果你的业务必须要写入Session到会话中,该方案不适用,请参考方案2。

方案2:后台异步执行任务(适配必须写Session的场景)

不要在请求主线程中同步执行耗时的DB查询逻辑,把耗时任务丢到后台线程池执行,当前请求先立即返回响应给前端,后台任务执行完成后再写入Session即可:

[System.Web.Services.WebMethod(EnableSession = true)]
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public SomeReponseDto LoadData(SomeRequestDto requestDto)
{
    // 提前取出需要的参数,避免后台线程丢失请求上下文
    var dataType = requestDto.Type;
    var sessionId = Session.SessionID;
    
    // 把耗时任务丢到后台线程执行,不阻塞当前请求
    _ = Task.Run(async () =>
    {
        var neededData = await GetDataFromDB();
        // 写入Session(如果后台拿不到当前HttpContext,可以通过SessionID用SessionStateUtility获取对应会话操作)
        if (HttpContext.Current != null)
        {
            // 补充:你原代码中的Session键拼接存在语法错误,此处已修正
            HttpContext.Current.Session[$"{dataType}_Data"] = neededData;
        }
    });
    
    // 直接返回任务已受理的响应,无需等待任务执行完成
    return new SomeResponseDto
    {
        Status = true,
        Message = $"Data for {dataType} are processing."
    };
}

方案3:全局调整Session默认权限(可选)

如果全站大部分接口都不需要写入Session,可直接在Web.config中配置全局Session为只读模式,仅给需要写入Session的单独接口开可写权限即可:

<system.web>
  <pages enableSessionState="ReadOnly" />
  <!-- 其余原有配置保持不变 -->
</system.web>

内容的提问来源于stack exchange,提问作者nizoodxs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:15:04