Cos*_*min 1 io task-parallel-library async-await asp.net-mvc-4
在MVC 4应用程序中,我有一个将文件复制到目标文件夹的任务.因为我有多个文件,所以我为每个文件创建一个任务,我想等到它们都完成了.问题是我的代码块Task.WaitAll(copyingTasks.ToArray())好像任务永远不会结束,所以它永远不会通过那行代码.下面是示例代码:
private void CopyFilesFromWorkingCopyForProject(string projectName)
{
var copyingTasks = new List<Task>
{
CopyAllFromDirectoryToDirectory(FilesUtils.AndroidConfigsPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyAllFromDirectoryToDirectory(FilesUtils.AndroidValuesPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyFileToDirectory(FilesUtils.AndroidManifestPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyAllFromDirectoryToDirectory(FilesUtils.IosConfigsPath(), FilesUtils.IosPathForProject(projectName))
};
Task.WaitAll(copyingTasks.ToArray());
}
private async Task CopyAllFromDirectoryToDirectory(string sourceDirectory, string destinationDirectory)
{
foreach (string filename in Directory.EnumerateFiles(sourceDirectory))
{
await CopyFileToDirectory(filename, destinationDirectory);
}
}
private async Task CopyFileToDirectory(string filename, string destinationDirectory)
{
using (FileStream sourceStream = File.Open(filename, FileMode.Open))
{
using (FileStream destinationStream = File.Create(destinationDirectory + filename.Substring(filename.LastIndexOf('\\'))))
{
await sourceStream.CopyToAsync(destinationStream);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我评论 Task.WaitAll(copyingTasks.ToArray());它不再阻止,但我想等待所有文件被复制.
svi*_*ick 11
组合await和同步等待会导致死锁,因为async方法会尝试在当前被等待阻止的上下文中恢复.
你应该做的,而不是是让CopyFilesFromWorkingCopyForProject()也async(和调用该方法,并调用该方法,...):
private async Task CopyFilesFromWorkingCopyForProject(string projectName)
{
var copyingTasks = new List<Task>
{
CopyAllFromDirectoryToDirectory(FilesUtils.AndroidConfigsPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyAllFromDirectoryToDirectory(FilesUtils.AndroidValuesPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyFileToDirectory(FilesUtils.AndroidManifestPath(), FilesUtils.AndroidPathForProject(projectName)),
CopyAllFromDirectoryToDirectory(FilesUtils.IosConfigsPath(), FilesUtils.IosPathForProject(projectName))
};
await Task.WhenAll(copyingTasks);
}
Run Code Online (Sandbox Code Playgroud)
如果您不能或不想这样做,则需要确保async方法不会在当前上下文中恢复.为此,您可以使用ConfigureAwait(false)所有awaits,或者您可以async使用后台线程调用方法Task.Run().
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |