【发布时间】:2011-02-28 11:23:22
【问题描述】:
我们有一个用于创建备份的相当简单的程序。我正在尝试并行化它,但在 AggregateException 中得到了 OutOfMemoryException。一些源文件夹非常大,程序在启动后大约 40 分钟内不会崩溃。我不知道从哪里开始寻找,所以下面的代码几乎是所有代码的准确转储,代码没有目录结构和异常日志记录代码。关于从哪里开始寻找的任何建议?
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
namespace SelfBackup
{
class Program
{
static readonly string[] saSrc = {
"\\src\\dir1\\",
//...
"\\src\\dirN\\", //this folder is over 6 GB
};
static readonly string[] saDest = {
"\\dest\\dir1\\",
//...
"\\dest\\dirN\\",
};
static void Main(string[] args)
{
Parallel.For(0, saDest.Length, i =>
{
try
{
if (Directory.Exists(sDest))
{
//Delete directory first so old stuff gets cleaned up
Directory.Delete(sDest, true);
}
//recursive function
clsCopyDirectory.copyDirectory(saSrc[i], sDest);
}
catch (Exception e)
{
//standard error logging
CL.EmailError();
}
});
}
}
///////////////////////////////////////
using System.IO;
using System.Threading.Tasks;
namespace SelfBackup
{
static class clsCopyDirectory
{
static public void copyDirectory(string Src, string Dst)
{
Directory.CreateDirectory(Dst);
/* Copy all the files in the folder
If and when .NET 4.0 is installed, change
Directory.GetFiles to Directory.Enumerate files for
slightly better performance.*/
Parallel.ForEach<string>(Directory.GetFiles(Src), file =>
{
/* An exception thrown here may be arbitrarily deep into
this recursive function there's also a good chance that
if one copy fails here, so too will other files in the
same directory, so we don't want to spam out hundreds of
error e-mails but we don't want to abort all together.
Instead, the best solution is probably to throw back up
to the original caller of copy directory an move on to
the next Src/Dst pair by not catching any possible
exception here.*/
File.Copy(file, //src
Path.Combine(Dst, Path.GetFileName(file)), //dest
true);//bool overwrite
});
//Call this function again for every directory in the folder.
Parallel.ForEach(Directory.GetDirectories(Src), dir =>
{
copyDirectory(dir, Path.Combine(Dst, Path.GetFileName(dir)));
});
}
}
线程调试窗口显示异常时有 417 个工作线程。
编辑: 复制是从一台服务器到另一台服务器。我现在正在尝试将最后一个 Paralell.ForEach 更改为常规 foreach 来运行代码。
【问题讨论】:
-
您通常是从磁盘 A 复制到磁盘 B,还是从同一磁盘上的一个位置复制到另一个位置?
标签: c#-3.0 parallel-processing out-of-memory .net