【发布时间】:2013-12-19 18:48:13
【问题描述】:
我有一种方法可以将一个目录中的所有文件和文件夹复制到另一个目录中,并且它以递归方式工作。我的问题是它阻塞了主线程,我想让文件和文件夹的实际复制异步。我目前正在使用一个函数来异步复制文件,但它似乎不起作用。 代码如下:
private async void copyEverything(string source, string target)
{
// Variable to hold the attributes of a file
FileAttributes attributes;
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(source);
DirectoryInfo[] dirs = dir.GetDirectories();
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: " + source);
}
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(target))
{
Directory.CreateDirectory(target);
}
// Loop through for all files in a directory
foreach (string filename in Directory.EnumerateFiles(source))
{
if (!File.Exists(targetFolder + filename.Substring(filename.LastIndexOf('\\'))))
{
attributes = File.GetAttributes(filename);
if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
//System.Windows.MessageBox.Show("File {" + filename + "} is READ ONLY");
}
else
{
try
{
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
using (FileStream DestinationStream = File.Create(target + filename.Substring(filename.LastIndexOf('\\'))))
{
await SourceStream.CopyToAsync(DestinationStream);
filesRemaining--;
}
}
}
catch (UnauthorizedAccessException)
{
}
}
}
}
// Loop through each subdirectory in the current directory and recursively call the
// copyEverything() method using the subdirectory's full name and the name of the
// target folder plus the subdirectory folder name
foreach (DirectoryInfo subdir in dirs)
{
foldersRemaining--;
string temppath = System.IO.Path.Combine(target, subdir.Name);
copyEverything(subdir.FullName, temppath);
}
}
有什么办法可以让它在不阻塞主线程的情况下工作吗?
【问题讨论】:
-
旁注,您可以通过让
EnumerateDirectories和EnumerateFiles使用搜索选项进行递归搜索,而不是使方法递归,从而大大提高性能。异步方法的递归比传统方法要昂贵得多。由于您似乎根本不需要在方法中使用 UI 上下文,您还可以在等待的任务上添加ConfigureAwait(false)。 -
对于每个递归文件/文件夹副本,都会有一个文件系统会溢出您的堆栈。
-
我很想分叉另一个进程来运行
robocopy
标签: c# multithreading asynchronous file-io copy