簡體   English   中英

多個異步文件上傳與分塊到 ASP.Net Web API

[英]Multiple Async File Uploads with chunking to ASP.Net Web API

我已經閱讀了許多密切相關的問題,但沒有一個完全符合這一點。 如果是重復的,請給我一個鏈接。

我正在使用 flowjs 庫的 angular 版本進行 HTML5 文件上傳( https://github.com/flowjs/ng-flow )。 這很好用,我能夠以 1MB 的塊同時上傳多個文件。 有一個 ASP.Net Web API 文件 controller 接受這些並將它們保存在磁盤上。 雖然我可以完成這項工作,但我沒有有效地完成它,並且想知道更好的方法。

首先,我在異步方法中使用了 MultipartFormDataStreamProvider,只要文件上傳到單個塊中,它就可以很好地工作。 然后我切換到只使用 FileStream 將文件寫入磁盤。 只要塊按順序到達,這也有效,但當然,我不能依賴這一點。

接下來,為了看到它的工作,我將塊寫入單個文件流並在事后將它們組合起來,因此效率低下。 一個 1GB 的文件會生成一千個需要在上傳完成后讀取和重寫的塊。 我可以在 memory 中保存所有文件塊並在它們全部上傳后刷新它們,但我擔心服務器會炸毀。

似乎應該有一個很好的異步解決方案來解決這個困境,但我不知道它是什么。 一種可能性可能是在寫入當前塊時使用async / await來組合先前的塊。 另一個可能是使用Begin / EndInvoke創建一個單獨的線程,以便獨立於從HttpContext讀取的線程處理磁盤上的文件操作,但這將依賴於ThreadPool並且我擔心創建的線程將被過度終止當我的 MVC controller 返回時。 我可以創建一個完全獨立於 ASP.Net 運行的FileWatcher ,但這會非常笨拙。

所以我的問題是,1)我已經缺少一個簡單的解決方案了嗎? (似乎應該有)和 2)如果沒有,在 Web API 框架內解決此問題的最佳方法是什么?

謝謝,鮑勃

我不熟悉那種分塊上傳,但我相信這應該有效:

  • 當第一個塊進入時,使用flowTotalSize 預分配文件
  • 每個文件都有一個SemaphoreSlim來序列化該文件的異步寫入。
  • 每個塊都將寫入文件中自己的偏移量flowChunkSize * (flowChunkNumber - 1) )。

這不會處理上載意外終止的情況。 這種解決方案通常涉及分配/寫入臨時文件(帶有特殊擴展名),然后在最后一個塊到達后移動/重命名該文件。

不要忘記確保您的文件寫入實際上是異步的

使用@Stephen Cleary的答案,以及這個帖子: https//github.com/flowjs/ng-flow/issues/41我能夠制作一個ASP.NET Web Api實現並上傳給那些仍然想知道這個問題的人作為@Herb Caudill

https://github.com/samhowes/NgFlowSample/tree/master

最初的答案是這個問題的真正答案,但我還沒有足夠的聲譽來評論。 我沒有使用SemaphoreSlim,而是啟用了文件寫共享。 但實際上是預先分配並確保通過計算偏移量將每個塊寫入正確的位置。

我將在以下網址為Flow示例做出貢獻: https//github.com/flowjs/flow.js/tree/master/samples

這就是我所做的。 上傳塊並將這些塊保存在服務器上,並保存數據庫中塊的位置及其順序(不是它們進入的順序,它們應該是文件中塊的順序)。

然后我引入了另一個端點來合並這些塊。 由於這部分可能是一個漫長的過程,因此我使用消息傳遞服務在后台運行該過程。

在服務完成合並文件后,發送通知(或者您可以觸發事件)。

同意,它不會解決必須保存所有這些塊的問題,但是在合並完成后,我們可以從磁盤中刪除它們。 然而,為了順利上傳,需要一些 IIS 配置。

這是我對這個老問題的兩分錢。 現在大多數應用程序使用 azure 或 aws 進行存儲。 但是,仍然分享我的想法,以防它幫助某人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM