我收到以下错误:
Exception Info: System.OutOfMemoryException
Stack:
at System.Threading.ExecutionContext.CreateCopy()
at System.Threading.Tasks.Task.CopyExecutionContext(System.Threading.ExecutionContext)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
at System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
该应用程序是一个c#windows服务(使用TopShelf)。该应用程序正在使用HanFire intitiate RunScan()方法。
我没有看到代码中的位置,但我怀疑它是添加到阻塞集合中。
代码:
public void RunScan(IJobCancellationToken cancellationToken, string path, int pathId)
{
SmartScanDAO scDAO = new SmartScanDAO();
PathInfo RootPathInfo = scDAO.ScanStarted(pathId);
try
{
if (RootPathInfo == null)
{
ErrorLogger.LogEvent(RootPathInfo.Id, string.Format("Path ({1}): {0} is null", path, pathId), EventLogEntryType.Error);
return;
}
if (RootPathInfo.Status == ScanStatus.Processing)
{
ErrorLogger.LogEvent(RootPathInfo.Id, string.Format("Path {0} is currently being scanned", path), EventLogEntryType.Information);
return;
}
RootPathInfo.Status = ScanStatus.Processing;
scDAO.ScanStatus(RootPathInfo);
ErrorLogger.LogEvent(string.Format("Scanning {0}", path), EventLogEntryType.Information);
if (!Directory.Exists(path))
{
scDAO.DisableIsilonScanPathById(RootPathInfo.Id);
ErrorLogger.LogEvent(RootPathInfo.Id, "The Path does not exists: " + path, EventLogEntryType.Error);
return;
}
// Get Directories to Skip
skipPaths = scDAO.GetDuplicateIsilonScanPaths(RootPathInfo.Path);
DirectoryInfo di = new DirectoryInfo(path);
SplunkExport.DeleteFiles(path, new List<string>() { "acl", "path" }, RootPathInfo.Id);
DirectoryType = (DirectoryType)Enum.Parse(typeof(DirectoryType), RootPathInfo.DirectoryType);
RootPathInfo.Path = di.FullName.ToLower();
RootPathInfo.Owner = GetAcl(RootPathInfo.Id, RootPathInfo.Path, DirectoryType, true, false, true);// SecurityUtils.GetOwner(di.FullName, (DirectoryType)Enum.Parse(typeof(DirectoryType), RootPathInfo.DirectoryType));
RootPathInfo.Files = 0;
RootPathInfo.Size = 0;
Interlocked.Add(ref FileCount, di.GetFiles().Length);
Interlocked.Add(ref DirectorySize, (int)di.GetFiles().Sum(f => f.Length));
Task<List<string>> outputMetaDataTask = Task.Factory.StartNew(() => WriteOutput(RootPathInfo.Path, SplunkFileType.MetaData, MetaDataQueue), TaskCreationOptions.LongRunning);
Task<List<string>> outputACLTask = Task.Factory.StartNew(() => WriteOutput(RootPathInfo.Path, SplunkFileType.ACL, ACLQueue), TaskCreationOptions.LongRunning);
Action action = (() => UpdateStats(RootPathInfo.Id, MetaDataQueue, ACLQueue));
CancellationTokenSource UpdateStatsToken = new CancellationTokenSource();
IObservable<long> observable = Observable.Interval(TimeSpan.FromMinutes(10));
// Subscribe the obserable to the task on execution.
observable.Subscribe(x =>
{
Task task = new Task(action); task.Start();
// task.ContinueWith(c => resumeAction());
}, UpdateStatsToken.Token);
MetaDataQueue.Add(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\"", DateTime.UtcNow + " UTC", di.FullName.ToLower(), 1, ((DirectoryInfo)di).GetFiles().Length, string.Format("{0:0.0}", ((DirectoryInfo)di).GetFiles().Sum(f => f.Length) / 1024 / 1024), RootPathInfo.Owner, di.LastAccessTimeUtc, di.CreationTimeUtc, di.LastWriteTimeUtc, ""));
//
// Traverse the path
GetSystemObjects(cancellationToken, di, RootPathInfo.Id, DirectoryType);
// Complete adding
MetaDataQueue.CompleteAdding();
ACLQueue.CompleteAdding();
// wait for
outputMetaDataTask.Wait();
outputACLTask.Wait();
//Send Files to Splunk
SplunkExport.CopyFilesToSplunk(outputMetaDataTask.Result, outputACLTask.Result, RootPathInfo.Id);
SmartScanDAO dao = new SmartScanDAO();
RootPathInfo.Size = DirectorySize;
}
catch (OperationCanceledException cex)
{
RootPathInfo.Status = ScanStatus.Cancelled;
if (scDAO == null)
scDAO = new SmartScanDAO();
scDAO.ScanStatus(RootPathInfo);
ErrorLogger.LogEvent(cex, RootPathInfo.Id);
}
catch (Exception ex)
{
if (RootPathInfo == null)
{
RootPathInfo = new PathInfo();
RootPathInfo.Id = pathId;
}
ErrorLogger.LogEvent(ex, RootPathInfo.Id);
RootPathInfo.Status = ScanStatus.Error;
if (scDAO == null)
scDAO = new SmartScanDAO();
scDAO.ScanStatus(RootPathInfo);
}
}
List<string> WriteOutput(string path, SplunkFileType fileType, BlockingCollection<string> queue)
{
var fileList = new List<string>();
int filecount = 1;
int linecount = 0;
int maxlinecount = 200000;
string header = (fileType.ToString() == SplunkFileType.ACL.ToString()?aclHeader:metaDataHeader);
var filepattern = SplunkExport.GetPaths(path, fileType.ToString());
string filename = string.Format(filepattern, filecount);
fileList.Add(filename);
while (true)
{
using (var strm = File.AppendText(filename))
{
foreach (var s in queue.GetConsumingEnumerable())
{
if (linecount == 0)
strm.WriteLine(header);
strm.WriteLine(s);
// if you want to make sure it's written to disk immediately,
// call Flush. This will slow performance, however.
strm.Flush();
linecount++;
if (linecount > maxlinecount)
{
linecount = 0;
filecount++;
break;
}
}
}
if (queue.IsCompleted)
break;
filename = string.Format(filepattern, filecount);
fileList.Add(filename);
}
return fileList;
}
private void GetSystemObjects(IJobCancellationToken cancellationToken, DirectoryInfo di, int pathid, DirectoryType directorytype = DirectoryType.Share)
{
long files = 0;
long size = 0;
int mb = 1024 * 1024;
try
{
Parallel.ForEach<FileSystemInfo>(di.EnumerateFileSystemInfos("*", System.IO.SearchOption.TopDirectoryOnly).Where(r => !r.FullName.Contains(@"\~snapshot") ), (FileSystemInfo fso) =>
{
if (skipPaths.Contains(fso.FullName))
return;
if (cancellationToken != null)
cancellationToken.ThrowIfCancellationRequested();
bool isDirectory = fso.EntryInfo.IsDirectory;
string owner = "";
owner = GetAcl(pathid, fso.FullName, directorytype, isDirectory, false);
try
{
if (isDirectory)
{
DirectoryInfo dis = new DirectoryInfo(fso.FullName);
lock (lckObject)
{
files = ((DirectoryInfo)fso).GetFiles().Length;
size = ((DirectoryInfo)fso).GetFiles().Sum(f => f.Length);
}
Interlocked.Add(ref FileCount, files);
Interlocked.Add(ref DirectorySize, size);
ErrorLogger.LogEvent(pathid, string.Format("Scan Directory\t{0}\t{1}", fso.FullName, files));
}
else
{
size = ((FileInfo)fso).Length;
files = 0;
}
MetaDataQueue.Add(string.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\"", DateTime.UtcNow + " UTC", fso.FullName.ToLower(), (fso.EntryInfo.IsDirectory ? 1 : 0), files, string.Format("{0:0.0}", size / mb), owner, fso.LastAccessTimeUtc, fso.CreationTimeUtc, fso.LastWriteTimeUtc));
}
catch (Exception ex)
{
ErrorLogger.LogEvent(ex, pathid);
}
if (isDirectory)
GetSystemObjects(cancellationToken, (DirectoryInfo)fso, pathid, directorytype);
fso = null;
}); // end of ForEach
}
catch (Exception ex)
{
ErrorLogger.LogEvent(ex, pathid);
}
}
可能发生错误或如何更接近根本原因的任何建议。在例外情况下,我没有看到任何指示。