- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 ASP.NET MVC 开发一个视频网站。
我想在我的应用程序中拥有的一个功能是转码视频。但由于转码过程可能非常耗时,我想向客户端用户展示该过程的进度。
因此,我的方案是使用一个 Controller 操作来处理整个转码过程,并将其进度写入存储在服务器上的文件中。同时我在转码过程中每2秒使用Ajax调用另一个controller action读取指定文件,获取进度信息并发送回客户端显示。
为了实现我的计划,我编写了以下代码:
服务器端:
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
操作方法都可以正常工作。问题在于,在 Transcode
操作完成其整个过程之前,永远不会调用 GetProgress
方法。那么我的代码有什么问题呢?我怎样才能修改它,使这两个 Action 自发地工作,从而实现我的目标?
更新
根据Alex的回答,我发现我的问题是由Asp.Net框架的session锁机制引起的。所以禁用我的VideoController
的SessionState
或者将其设置为只读确实使得 Controller 在执行转码视频的action方法时响应获取转码进度的请求.但是因为我在我的 VideoController
中使用了 Session
来存储一些跨多个请求使用的变量,所以这种方式不是解决我的问题的合适方法。有没有更好的办法解决?
最佳答案
您误解了关于异步/等待的全部要点。它不会改变这样一个事实,即对于每个请求,都会返回一个响应。当您在操作中调用 await 时,尚未向客户端返回任何内容。它唯一做的事情(在一个非常高的抽象层次上)是将处理这个请求的当前线程释放到一个线程池,这样它就可以用于处理其他请求。所以基本上它允许您更有效地使用您的服务器资源,因为没有线程被浪费在等待长时间的 I/O 操作完成。一旦 I/O 操作完成,操作(调用 await)的执行就会继续。只有在操作结束时,响应才会发送到客户端。
至于你的场景,如果它是一个长时间运行的任务,我会使用某种后台处理解决方案,比如 Hangfire并使用 SignalR 从服务器推送更新。 Here is an example
您也可以自己实现类似的功能 (example)。
更新:正如@Menahem 在他的评论中所说,我可能误解了你的部分问题。
请求排队问题可能是由于SessionStateBehavior配置不正确引起的.自 MvcHandler ASP.NET MVC 使用的处理程序标有 IRequiresSessionState接口(interface),每次 session 只能处理一个请求。为了改变它,让你的 Controller 无 session (或者至少确保你没有写入这个 Controller 中的 session )并将其标记为[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
属性。
关于c# - 对 Action 方法的两个并行 ajax 请求排队,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40447801/
我有一些基于 TThreads 的操作。现在我需要创建包含要完成的作业列表的线程,然后在前一个完成后立即触发每个线程...我应该如何编写它?我不能允许线程同时运行,因为可能有超过 10 000 个操作
我正在尝试使用 RxJS 来实现服务调用限制/排队。 例如,Google Maps 的 Geocoder API。假设我不希望它每秒被调用一次以上,但是我的应用程序的一个或多个部分可能会比这更频繁
我目前正在通过 freecodecamp 网站的 javascript 部分进行练习,我试图理解为什么特定的方法可以解决它。 function nextInLine(arr, item) { /
详情 我有一个带有动画的功能,当点击按钮时它会.append一个div到body。然后,div 将为其位置向下移动一点点设置动画。添加另一个时,所有 div 也会向下移动,因此它们不会重叠。 现在我们
我有一个正在发送 http 请求的应用程序,每次用户键入时都会返回一个 promise 。我让它每 500 毫秒去抖一次。有时我请求的 api 需要很长时间才能响应。例如,我对 a 发出搜索请求,该请
我一直在做一项作业,涉及实现包含空指针的队列,以便它们可以针对任何类型的数据进行泛化。我目前遇到一个奇怪的问题,虽然出队节点减少了列表的大小但没有返回我期望的节点。在出列操作中省略对 free() 的
我正在寻找概述“排队”的文章和引用资料(我在这里可能甚至没有使用正确的术语)。我希望通过 Redis、RabbitMQ、Celery、Kombu 以及我尚未了解的任何其他组件以及它们如何组合在一起的世
我使用 mbostock/queue用于排队一些异步操作。更多的是速率限制(UI 生成的事件很少,后端可以慢慢处理),并确保它们按顺序处理。我像这样使用它 function request(d, cb
我有我的 android 应用程序,它不是为离线工作而构建的,因此它依赖于网络连接/数据。 应用程序进行大量网络调用,使用新数据集更新 api。 我正在对其进行更改以使其脱机工作。 方法我想我将创建一
我想将 div 的内容更改 3 次,每次更改之间延迟 1 秒。delay() 在此代码中不起作用: $('#import-status-msg').html('Importing content ..
我需要根据存储在数据库中的时间线在 jQuery 中制作一系列动画。我将这些信息与函数名称(动画、幻灯片、淡入淡出...)、函数的选项/参数以及函数的回调一起存储。 我知道 jQuery 确实有 .q
我有以下方法 public async Task SomeMethod(parameters) { // here we execute some instructions which are
在我的 winforms 应用程序中,我有一个包含对象的队列: Queue _queuedRows = new Queue(); 对于每个对象,我必须启动一个单独的 backgroundwor
我有以下代码: for (int i = 1; i <= 500; i++) { BackgroundWorker t = new BackgroundWorker(); t.DoWo
我有一个 CAShapeLayer,我在其中设置了一个圆圈的动画。动画是先顺时针“撤消”圆圈,然后顺时针重画圆圈。有点像“旋转圈”。另一种说法是:将路径描边终点移动到起点,然后将起点移到终点。 动画本
所以,在前一段时间了解完成 block 之后,我非常喜欢使用完成 block 。我喜欢关闭,我喜欢将任何东西传递到任何我想要的地方的能力。 作为线程编程的新手,我一直远离 GCD 和 NSOperat
我有一些使用 FMDB sqllite 包装器 ( https://github.com/ccgus/fmdb ) 的代码,并且我希望从多个线程执行此代码。因此,我使用 FMDatabaseQueue
页面加载速度比预期慢。我用 Firebug 检查了时间线,我看到很多图像阻塞: http://i.imgur.com/tenTNVH.png 我想我做错了什么。 (我知道我这里有双 jquery,会消
我在使用 Alamofire 时遇到任务执行问题我使用了两次 Alamofire,第一次是收集数据( token ),然后我将使用它来发送我的 Post 请求。 我的两次请求之间的问题,数据的恢复是在
我想知道如何将选定的 YouTube 视频添加到临时播放列表/播放队列中? 我有一个选项,用户必须选择要包含在播放队列中的所有视频。 Click on the ADD icon (black back
我是一名优秀的程序员,十分优秀!