对 Action 方法的两个并行 ajax 请求排队,为什么?

2024-06-21

我正在使用 ASP.NET MVC 开发一个视频网站。

我希望在我的应用程序中拥有的一项功能是转码视频。但由于转码过程可能非常耗时,我想向客户端用户展示该过程的进度。

因此,我的架构是使用一个控制器操作来处理整个转码过程,并将其进度写入存储在服务器上的文件中。同时,在转码过程中,我使用Ajax调用另一个控制器动作来读取指定文件,检索进度信息并将其发送回客户端显示,每2秒一次。

为了实现我的计划,我编写了以下代码:

服务器端:

public class VideoController : Controller
{
         //Other action methods
         ....
    //Action method for transcoding a video given by its id
    [HttpPost]
    public async Task<ActionResult> Transcode(int vid=0)
    {
        VideoModel VideoModel = new VideoModel();
        Video video = VideoModel.GetVideo(vid);
        string src = Server.MapPath("~/videos/")+video.Path;
        string trg = Server.MapPath("~/videos/") + +video.Id+".mp4";
        //The file that stores the progress information
        string logPath = Server.MapPath("~/videos/") + "transcode.txt";
        string pathHeader=Server.MapPath("../");

        if (await VideoModel.ConvertVideo(src.Trim(), trg.Trim(), logPath))
        {
            return Json(new { result = "" }); 
        }
        else
        {
          return Json(new { result = "Transcoding failed, please try again." });
        }
    }

    //Action method for retrieving the progress value from the specified log file
    public ActionResult GetProgress()
    {
        string logPath = Server.MapPath("~/videos/") + "transcode.txt";
        //Retrive the progress from the specified log file.
        ...
        return Json(new { progress = progress });
    }
}

客户端:

var progressTimer = null;
var TranscodeProgress = null;

// The function that requests server for handling the transcoding process
function Transcode(vid) {
    // Calls the Transcode action in VideoController
    var htmlobj = $.ajax({
        url: "/Video/Transcode",
        type: "POST",
        //dataType: 'JSON',
        data: { 'vid': vid },
        success: function(data)
        {
        if(data.result!="")
            alert(data.result);
        }
        else
        {
          //finalization works
          ....
        }
    }
    });
    //Wait for 1 seconds to start retrieving transcoding progress
    progressTimer=setTimeout(function ()
    {
        //Display progress bar
        ...
       //Set up the procedure of retrieving progress every 2 seconds
        TranscodeProgress = setInterval(Transcoding, 2000);
    }, 1000);
}

//The function that requests the server for retrieving the progress information every 2 seconds.
function Transcoding()
{
    //Calls the GetProgress action in VideoController
    $.ajax({
        url: "/Video/GetProgress",
    type: "POST",
    //dataType: 'JSON',
    success: function (data)
    {
        if (data.progress == undefined || data.progress == null)
            return;
        progressPerc = parseFloat(data.progress);
        //Update progress bar
        ...
    }
  });
}

现在是客户端代码和Transcode动作方法一切正常。问题是GetProgress方法永远不会被调用,直到Transcode动作完成了它的整个过程。那么我的代码有什么问题吗?我该如何修改它,使这两个动作自发地发挥作用,从而实现我的目标?

Update

根据Alex的回答,我发现我的问题是由Asp.Net框架的会话锁定机制引起的。所以禁用SessionState of my VideoController或者将其设置为只读确实会使控制器在执行转码视频的操作方法时响应检索转码进度的请求。但因为我用Session in my VideoController要存储一些变量以便在多个请求中使用,这种方式不能成为解决我的问题的合适解决方案。有没有更好的方法来解决呢?


您误解了有关 async/await 的全部要点。它不会改变这样的事实:对于每个单个请求,都会返回一个响应。当您在操作中调用等待时,尚未向客户端返回任何内容。它所做的唯一事情(在非常高的抽象级别中)是将处理此请求的当前线程释放到线程池,以便它可以用于处理其他请求。因此,基本上它可以让您更有效地使用服务器资源,因为没有线程浪费时间等待长时间 I/O 操作完成。一旦 I/O 操作完成,操作(调用等待)的执行就会继续。仅在操作结束时,响应才会发送到客户端。

至于你的场景,如果它是一个长时间运行的任务,我会使用某种后台处理解决方案,例如Hangfire http://hangfire.io/并使用 SignalR 从服务器推送更新。这是一个例子 http://docs.hangfire.io/en/latest/background-processing/tracking-progress.html

您也可以自己实现类似的东西(example https://www.safaribooksonline.com/blog/2014/02/06/server-side-signalr/).

UPDATE: 正如@Menahem 在他的评论中所说,我可能误解了你问题的一部分。

请求排队问题可能是由于配置不正确造成的会话状态行为 https://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstatebehavior(v=vs.110).aspx. Since MvcHandler https://msdn.microsoft.com/en-us/library/system.web.mvc.mvchandler(v=vs.118).aspxASP.NET MVC 使用的处理程序标记为IRequiresSessionState https://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate(v=vs.110).aspx接口,每个会话一次只能处理一个请求。为了改变这一点,使您的控制器无会话(或者至少确保您没有写入此控制器中的会话)并将其标记为[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对 Action 方法的两个并行 ajax 请求排队,为什么? 的相关文章

  • 在新的浏览器进程中打开 URL

    我需要在新的浏览器进程中打开 URL 当浏览器进程退出时我需要收到通知 我当前使用的代码如下 Process browser new Process browser EnableRaisingEvents true browser Star
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 如何从 .resx 文件条目获取注释

    资源文件中的字符串有名称 值和注释 The ResXResourceReader类让我可以访问名称和值 有办法看评论吗 你应该能够得到Comment via ResXDataNode class http msdn microsoft co
  • 将 System.Windows.Input.KeyEventArgs 键转换为 char

    我需要将事件参数作为char 但是当我尝试转换 Key 枚举时 我得到的字母和符号与传入的字母和符号完全不同 如何正确地将密钥转换为字符 这是我尝试过的 ObserveKeyStroke this new ObervableKeyStrok
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 未定义的行为或误报

    我 基本上 在野外遇到过以下情况 x x 5 显然 它可以在早期版本的 gcc 下编译干净 在 gcc 4 5 1 下生成警告 据我所知 警告是由 Wsequence point 生成的 所以我的问题是 这是否违反了标准中关于在序列点之间操
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • 如何对 Web Api 操作进行后调用?

    我创建了一个 Web API 操作 如下所示 HttpPost public void Load string siteName string providerName UserDetails userDetails implementat
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • 如果方法参数是 string 或 int,ASP.NET WebAPI 会抛出 404

    我对 ASP NET MVC4 WebAPI 做了一个非常简单的测试 发现了一些有趣的问题 当一个方法采用复杂类型时 它会起作用 但是当它采用 string 或 int 时 它将抛出 404 如给出的屏幕截图所示 AddProduct 可以
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi

随机推荐

  • CSS 旋转轮在 5 秒后停止?

    我正在使用我在小提琴上找到的 CSS 代码来旋转我的轮子 http jsfiddle net gaby 9Ryvs 7 http jsfiddle net gaby 9Ryvs 7 div margin 20px width 100px h
  • C# 中的 mshtml.HTMLDocumentClass

    在 C 中 我设法从 InternetExplorer 对象获取整个 HTMLDocumentClass 导航到某个 URL 然而 在 Visual Studio 2008 的调试模式下 该特定 URL 的 HTMLDocumentClas
  • issubclass() 对从不同路径导入的同一类返回 False

    目的是实现某种插件框架 其中插件是同一基类 即 A 的子类 即 B 基类使用标准导入加载 而子类使用 imp load module 从众所周知的包 即 pkg 的路径加载 pkg init py mod1 py class A mod2
  • Docker-compose 和 Rails 控制台问题。 “在任何来源中都找不到 rake-13.0.6”

    尝试在 docker 下运行 Rails 控制台时遇到一些问题 所有其他 Rails 命令都按预期工作 但控制台却不然 octopus git master docker compose run web bundle exec rails
  • 如何在 JavaScript 中获取浮点数的小数位?

    我想要的是与 Number prototype toPrecision 几乎相反的 这意味着当我有数字时 它有多少位小数 例如 12 3456 getDecimals 4 对于任何想知道如何更快地完成此操作 无需转换为字符串 的人 这里有一
  • TYPE_ACCELEROMETER 和 TYPE_LINEAR_ACCELERATION 传感器有什么区别?

    I think TYPE ACCELEROMETER显示设备加速 但是 我不明白什么时候应该使用TYPE LINEAR ACCELERATION 我需要计算移动设备的速度 哪种传感器适合此应用 另外 我读到TYPE LINEAR ACCEL
  • 在测试期间调用预定方法[重复]

    这个问题在这里已经有答案了 我正在使用 Maven 开发 SpringBoot 应用程序 我有一个班级 Component有方法的注释m与 Scheduled initialDelay 1000 fixedDelay 5000 注解 这里f
  • 从 Angular2 模块导出时遇到问题

    我是 Angular 2 的初学者 我试图了解如何从功能模块导出类 并将其导入到我的主模块中 当我尝试在打字稿中编译它时 我收到以下两个错误 app app component ts 11 21 错误 TS2304 找不到名称 添加服务 a
  • Laravel 使用 laravel-cors 和 axios 进行 POST 的“CSRF 令牌不匹配”

    我有一个正在运行的domain A拉拉维尔 5 8返回 API 的引擎网络路线 它必须检查来源才能只服务几个域 包括domain B Barryvdh laravel cors我安装了barryvdh laravel cors https
  • 在Python中从日期时间中减去秒

    我有一个 int 变量 它实际上是秒 让我们调用这个秒数X 我需要得到当前日期和时间 以日期时间格式 减去的结果X秒 Example If X是 65 当前日期是2014 06 03 15 45 00 那么我需要得到结果2014 06 03
  • 在数据库准备好之前运行 Jest 测试

    我正在使用 Jest 来测试我的带有 SQLite 数据库的 Express API 但是出现了以下问题 测试在数据库准备好并创建表之前运行 我使用以下代码连接到数据库 const connectToDatabase gt let db i
  • GitLab Runner 重启后不会自动拾取作业

    所以我们的 GitLab Runner 已经正常运行了几周了 我必须进行一些升级 需要在安装它的计算机上重新启动 重新启动后 它不再自动拾取作业 我所有的管道都说它们被卡住了 因为没有跑步者可以接替工作 我通过 SSH 连接到机器并运行 s
  • RecyclerView元素更新+异步网络调用

    我有一个按预期工作的回收视图 我的布局中有一个按钮可以填充列表 该按钮应该进行异步调用 根据结果 我更改按钮的外观 这一切都发生得很好 但是 当我单击按钮并快速向下滚动列表时 异步调用的结果会更新新视图的按钮 代替旧视图的视图 我该如何处理
  • iOS 上的推送通知渐进式 Web 应用程序

    我需要开发一个集成了推送通知的渐进式网络应用程序 在网上搜索我发现了关于这个主题的不同意见 如果我理解正确的话 目前我们无法在移动版 safari 中推送通知 但仅限桌面版 这样对吗 你有什么建议来获得相同的结果吗 我不是iOS专家 我想知
  • 在游戏中实现功能

    我在完成这部分作业时遇到了麻烦 我必须宣布游戏的获胜者 然后输入到函数中 输入所有 if 语句后 我必须创建一个函数def playGame 这必须包括 showRules user getUserChoice computer getCo
  • 无法在 mongodb 中创建角色

    我正在尝试在 mongodb 中创建一个新角色 但它给了我错误 gt use Admin switched to db Admin gt db createRole role executeFunctions privileges reso
  • 使用属性和性能

    我正在优化我的代码 我注意到使用属性 甚至自动属性 对执行时间有深远的影响 请参阅下面的示例 Test public void GetterVsField PropertyTest propertyTest new PropertyTest
  • SambaFileInputStream 和 FileInputStream 有什么不同?

    我需要从 samba 服务器流式传输视频 并且我使用 nanohttpd 在我的项目中创建简单的服务器 当我使用本地文件中的 fileinputstream 时 视频视图可以按设置播放视频 http localhost 8080 publi
  • 如何在ExtJs商店中使用过滤器?

    我使用 ExtJs 创建了一个商店 我想将商店的值加载到 ComboBox 但在加载值之前 我需要根据另一个组合框中选择的值过滤一些数据 因此 为了这个目的 我认为我需要在商店应用过滤器 请任何人都可以帮助我如何做到这一点 Model Ex
  • 对 Action 方法的两个并行 ajax 请求排队,为什么?

    我正在使用 ASP NET MVC 开发一个视频网站 我希望在我的应用程序中拥有的一项功能是转码视频 但由于转码过程可能非常耗时 我想向客户端用户展示该过程的进度 因此 我的架构是使用一个控制器操作来处理整个转码过程 并将其进度写入存储在服