我应该将我的操作方法转换为异步操作方法吗?



我有一个网站,用户可以上传PDF并将其转换为WORD文档。

它工作得很好,但有时(每小时 5-6 次)用户必须比平时等待更多的时间才能进行转换......

我使用 MVC ASP.NET 流程为:- 用户上传文件 ->获取流并将其转换为单词 ->将Word文件另存为临时文件 ->返回用户网址

我不确定是否必须将此流转换为异步?基本上,我的流程现在是顺序的,但我每秒大约有 3-5 个请求,CPU 是双核和 4 GB RAM。

据我所知,maxConcurrentRequestsPerCPU is 5000 ; 也The default value of Threads Per Processor Limit is 25 ; 所以这些默认设置应该很好,对吧?

那为什么我的网络应用程序仍然有"等待"的时间呢?是否有任何 IIS 设置需要从默认值修改为其他任何设置,或者我应该去使我的同步转换方法异步?

Ps:转换本身需要 1 秒到 40-50 秒,具体取决于 pdf 文件大小。

更新:基本上对我来说不太清楚的是:如果用户上传文件并且转换时间很长,那么只有当前请求不应该因此而"受苦"吗?因为下一个请求是独立的,所以进行另一个 CPU 调用和不同的线程,所以不应该在这里等待,不是吗?

这里有几件事必须明确定义。异步(hronous)方法和流至少据我所知不是一回事。

异步方法(使用 Task,通常也利用 async/await 关键字)将按以下方式工作:

  1. 执行在线程 t1 上开始,直到到达 await
  2. (可能)长时间的操作不会在线程 t1 上进行 - 有时甚至根本不会在应用程序线程上发生,利用 IOCP(I/O 完成端口)。
  3. 线程
  4. t1 是空闲的,并释放回线程池,并准备好在需要时为其他请求提供服务
  5. 当(可能)长操作返回一个线程时,从线程池中获取一个线程(甚至可能是相同的 t1,或者很可能是另一个),并且其余的代码执行从遇到的最后一个等待中恢复
  6. 其余
  7. 代码执行

这里有几点需要注意:

一个。客户端在整个过程中被阻止。线程等的最终切换仅在服务器上发生b.此方法主要用于缓解称为"线程不足"的不需要的情况。它并不意味着加快客户等待的总时间,通常不会加快该过程。

据我了解,异步流意味着,至少在这种情况下,在用户请求转换文档后,客户端(即客户端的浏览器)将很快收到响应,其中他被告知这个潜在的长时间进程已经在服务器上启动,用户应该耐心等待,这个当前的响应页面可能会提供进度反馈。


在您的情况下,我推荐第二种方法,因为第一种方法根本没有帮助。

当然,这并不容易。您需要模拟队列,您需要有一个处理代理和一个逐出策略(如果您不需要第二个代理,则很可能由同一代理强制执行)。

这将按照以下思路工作:

一个。最终用户提交文件,Web 服务器接收文件b.Web 服务器将其放入队列中并接收作业编号c. Web 服务器向用户返回带有作业编号的响应(假设一个具有轮询机制的 HTML 页面会定期从服务器接收进度)d. 代理将在有机会(即完成其他工作)时开始处理文档,并在公共位置更新其状态,以便 Web 服务器选择此信息e.Web 服务器将接收来自 HTML 响应的调用,询问作业的状态,并发现作业已完成并提供下载链接或直接开始下载。

这可以通过一些方式进行优化:

  1. 可以使用 websocket 或长轮询(例如 SignalR 涵盖两者)代替客户端轮询服务器
  2. 如果硬件配置有意义,则可以使用许多处理代理而不是一个

队列可以用一个简单的RDBMS来实现,Remus Ruřanu有一篇很好的文章。

最新更新