2013-07-23 38 views
1

在MVC 4應用程序中,我有一個將文件複製到目標文件夾的任務。因爲我有多個文件,所以我爲每個文件創建一個任務,並且我想等到他們完成。問題是我的代碼塊在Task.WaitAll(copyingTasks.ToArray()),好像這些任務永遠不會結束,所以它永遠不會傳遞那行代碼。下面你有示例代碼:MVC 4應用程序上的Task.WaitAll(...)塊

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,也可以使用Task.Run()在後臺線程上調用async方法。

相關問題