우리는 백업 생성에 사용되는 프로그램이 매우 간단합니다. 그것을 병렬 처리하려고하지만 AggregateException 내에서 OutOfMemoryException이 발생합니다. 원본 폴더 중 일부는 매우 크며 프로그램을 시작한 후 약 40 분 동안 충돌하지 않습니다. 어디서부터 시작해야할지 모르겠다. 아래의 코드는 모든 코드의 정확한 덤프이며, 디렉토리 구조와 예외 로깅 코드는 없다. 어디서부터 시작해야할지 조언 해주세요.Parallel.For System.OutOfMemoryException
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로 복사 하시겠습니까? 아니면 동일한 디스크의 한 위치에서 다른 위치로 복사 하시겠습니까? –