c# - 分块到 ASP.Net Web API 的多个异步文件上传

标签 c# asp.net multithreading asynchronous asp.net-web-api

我已经阅读了许多密切相关的问题,但没有一个完全符合这个问题。如果重复,请给我一个链接。

我正在使用 flowjs 库的角度版本来上传 HTML5 文件 (https://github.com/flowjs/ng-flow)。这非常有效,我能够以 1MB 的 block 同时上传多个文件。有一个 ASP.Net Web API 文件 Controller 接受这些并将它们保存在磁盘上。虽然我可以做到这一点,但我做起来效率不高,想知道更好的方法。

首先,我在异步方法中使用了 MultipartFormDataStreamProvider,只要文件以单个 block 上传,该方法就可以很好地工作。然后我切换到只使用 FileStream 将文件写入磁盘。只要 block 按顺序到达,这也有效,但当然,我不能依赖它。

接下来,为了看看它是否有效,我将 block 写入单独的文件流并在事后组合它们,因此效率低下。一个 1GB 的文件会生成一千个 block ,上传完成后需要读取和重写这些 block 。我可以将所有文件 block 保存在内存中并在它们全部上传后刷新它们,但我担心服务器会崩溃。

似乎应该有一个很好的异步解决方案来解决这个难题,但我不知道它是什么。一种可能是在写入当前 block 时使用 async/await 组合先前的 block 。另一种方法可能是使用 Begin/EndInvoke 创建一个单独的线程,以便独立于从 HttpContext 中读取的线程处理磁盘上的文件操作> 但这将依赖于 ThreadPool 并且我担心创建的线程会在我的 MVC Controller 返回时被不当终止。我可以创建一个完全独立于 ASP.Net 运行的 FileWatcher,但这会非常笨拙。

所以我的问题是,1) 是否已经有一个我缺少的简单解决方案? (似乎应该有)和 2) 如果没有,在 Web API 框架内解决这个问题的最佳方法是什么?

谢谢,鲍勃

最佳答案

我不熟悉那种分块上传,但我相信这应该可行:

  • 使用flowTotalSizepre-allocate the file当第一个 block 进来时。
  • 每个文件有一个 SemaphoreSlim 来序列化该文件的异步写入。
  • 每个 block 将 write to its own offset (flowChunkSize * (flowChunkNumber - 1)) 在文件中。

这不会处理上传意外终止的情况。这种解决方案通常涉及分配/写入临时文件(具有特殊扩展名),然后在最后一个 block 到达后移动/重命名该文件。

别忘了 ensure that your file writing is actually asynchronous .

关于c# - 分块到 ASP.Net Web API 的多个异步文件上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23520921/

相关文章:

c# 在 for 循环中创建对象的新实例

c# - 根据当前 URL 生成 URL 并维护 QueryString

c# - 为 ASP.NET 中继器中的 LinkBut​​ton 设置额外属性

asp.net - 将 ASP.NET Web 窗体托管为 Windows Azure 网站

java - 如何阻止一个线程修改另一个线程正在使用的数组?

c# - 如何在 asp core 2 中播种用户身份属性?

c# - ASP.NET MVC 4.0 Controller 和 MEF,如何将这两者结合在一起?

c# - 单击 asp.net 按钮时如何关闭 Html 窗口?

c# - 如何使用 HostBuilder Generic Host ref StopAsync OperationCanceledException 设置 ShutdownTimeout

java - 在匿名线程中使用最终变量