2013-07-23 4 views
1

В приложении MVC 4 у меня есть задача, которая копирует файл в папку назначения. Поскольку у меня есть несколько файлов, я создаю задачу для каждого файла, и я хочу ждать, пока они не закончатся. Проблема заключается в том, что мои кодовые блоки на Task.WaitAll(copyingTasks.ToArray()), как будто задачи никогда не заканчиваются, поэтому она никогда не пропускает эту строку кода. Ниже есть пример кода:Task.WaitAll (...) блокирует приложение MVC 4

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); 
      } 
     } 
    } 

Если я комментирую Task.WaitAll(copyingTasks.ToArray()); не блокирует больше, но я хочу, чтобы ждать, пока все файлы, которые будут скопированы.

+0

И есть ли какое-либо копирование? Я не вижу, где запускаются задачи. –

ответ

10

Combining await and synchronous wait leads to deadlocks, потому что методы 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); 
} 

Если вы не можете или не хотите для этого вам необходимо убедиться, что методы async не возобновляются в текущем контексте. Для этого вы можете использовать ConfigureAwait(false) для всех своих await s, или вы можете вызвать методы async на фоновом потоке, используя Task.Run().

Смежные вопросы