为什么?当我保存2张图片时,第一个保存已损坏,第二个未保存 全部保存
我想保存文件而不卡住客户端(Task.Run),并且 不会卡住服务器(异步等待)
Task.Run(async () => {
foreach (var item in Images)
{
// item.File is IFormFile array
await SaveFile(item.FileSavePath, item.File);
}
});
public static async Task SaveFile(string filePath, IFormFile file)
{
string folderPath = Path.GetDirectoryName(filePath);
if (!Directory.Exists(folderPath))
Directory.CreateDirectory(folderPath);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
答案 0 :(得分:1)
如果不等待Task.Run
,那么几乎可以肯定会在实际的SaveFile
任务完成之前返回该操作。当操作超出范围时,它将带走其所有范围变量,包括从帖子主体绑定的IFormFile
实例。这将导致写入被过早取消,从而使您留下损坏的文件(因为在写入过程中流被破坏了)。将引发异常,但是由于您正在新线程中运行,因此该异常不会在请求管道中冒泡,并且会被有效吞咽。
长而短,请等待您打给Task.Run
的电话。但是,一旦这样做,那么在这里使用Task.Run
实际上是没有意义的。因此,最好完全摆脱它。相反,只需解开所有任务,然后等待Task.WhenAll
:
var tasks = new List<Task>();
foreach (var item in Images)
{
// item.File is IFormFile array
tasks.Add(SaveFile(item.FileSavePath, item.File));
}
await Task.WhenAll(tasks);
任务热返回或已启动。这样,等待每个项目保存在foreach中将导致串行处理任务。仅将它们保存到列表中,就可以使它们全部并行启动和运行。然后,您只需要等待列表中所有任务的完成即可避免操作返回,直到工作完成为止。