問題:Request.Content.ReadAsMultipartAsync never returns
應用於使用FormData封包上傳(多段MIME)檔案時會卡住的狀況。有人查出原因是執行緒被自已鎖住。
修正前程式碼
/// 使用FormData封包上傳檔案之失敗例子
[HttpPost]
public string UploadFileSample_BAD()
{
try
{
bool isMimeContent = Request.Content.IsMimeMultipartContent();
var provider = Request.Content.ReadAsMultipartAsync().Result;
/// 使用 Task.Wait/Task.Result 同步語法將會自己鎖死自己的thread! Orz
/// 然而改用 async/await 非同步語去就正常了。
...
return $"SUCCESS";
}
catch (Exception ex)
{
return "我失敗了嗚嗚!";
}
}
修正後程式碼
改用非同步語法(async/await)即可避開此問題。
/// <summary>
/// 使用FormData封包上傳檔案
/// </summary>
[HttpPost]
public async Task<string> UploadFileSample()
{
try
{
//# 開始解析[MultipartFormDataContent]封包
bool isMimeContent = Request.Content.IsMimeMultipartContent();
var provider = await Request.Content.ReadAsMultipartAsync();
/// 使用 Task.Wait/Task.Result 同步語法將會自己鎖死自己的thread!
/// 然而改用 async/await 非同步語去就正常了。
/// 再依FormData封包規格自行一一解開內容。
/// 本案例第一個Content放資料,第二個之後放附件
//# 解開資料封包
var reqContent = provider.Contents[0].ReadAsStringAsync().Result;
var req = JsonConvert.DeserializeObject<YourFormInfo>(reqContent);
//# 解開附件封包
var streamList = new List<YourStreamInfo>();
for (int i = 1; i < provider.Contents.Count; i++)
{
var content = provider.Contents[i];
streamList.Add(new YourStreamInfo {
name = content.Headers.ContentDisposition.Name,
fileName = content.Headers.ContentDisposition.FileName,
fileStream = content.ReadAsStreamAsync().Result
});
}
// ...後續處理
return $"SUCCESS;
}
catch (Exception ex)
{
return "我失敗了嗚嗚!";
}
}
參考
Last updated