C# 异常信息:System.OutOfMemoryException
我收到以下错误:C# 异常信息:System.OutOfMemoryException,c#,windows-services,hangfire,C#,Windows Services,Hangfire,我收到以下错误: Exception Info: System.OutOfMemoryException Stack: at System.Threading.ExecutionContext.CreateCopy() at System.Threading.Tasks.Task.CopyExecutionContext(System.Threading.ExecutionContext) at System.Threading.Tasks.Task.ExecuteWithTh
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 Initiate 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);
}
}
public void运行扫描(IJobCancellationToken cancellationToken,字符串路径,int-pathId)
{
SmartScanDAO scDAO=新SmartScanDAO();
PathInfo RootPathInfo=scDAO.ScanStarted(路径ID);
尝试
{
if(RootPathInfo==null)
{
LogEvent(RootPathInfo.Id,string.Format(“路径({1}):{0}为null”,路径,路径Id),EventLogEntryType.Error);
返回;
}
if(RootPathInfo.Status==ScanStatus.Processing)
{
ErrorLogger.LogEvent(RootPathInfo.Id,string.Format(“当前正在扫描路径{0}”),EventLogEntryType.Information);
返回;
}
RootPathInfo.Status=ScanStatus.Processing;
scDAO.ScanStatus(RootPathInfo);
LogEvent(string.Format(“扫描{0}”,路径),EventLogEntryType.Information);
如果(!Directory.Exists(path))
{
DisableIsilonScanPathById(RootPathInfo.Id);
ErrorLogger.LogEvent(RootPathInfo.Id,“路径不存在:”+Path,EventLogEntryType.Error);
返回;
}
//获取要跳过的目录
skipPaths=scDAO.getDuplicateSilonScanPaths(RootPathInfo.Path);
DirectoryInfo di=新的DirectoryInfo(路径);
删除文件(路径,新列表(){“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;
添加(ref FileCount,di.GetFiles().Length);
Add(ref DirectorySize,(int)di.GetFiles().Sum(f=>f.Length));
Task outputMetaDataTask=Task.Factory.StartNew(()=>WriteOutput(RootPathInfo.Path,SplunkFileType.MetaData,MetaDataQueue),TaskCreationOptions.LongRunning);
Task outputACLTask=Task.Factory.StartNew(()=>WriteOutput(RootPathInfo.Path,SplunkFileType.ACL,ACLQueue),TaskCreationOptions.LongRunning);
Action Action=(()=>UpdateStats(RootPathInfo.Id、MetaDataQueue、ACLQueue));
CancellationTokenSource UpdateStatsToken=新的CancellationTokenSource();
IObservable-observable=可观测的时间间隔(TimeSpan.frommins(10));
//在任务执行时订阅可观察内容。
可观察。订阅(x=>
{
Task Task=新任务(操作);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}\”、“{8}\”)、“{8}\”).f.1024文件长度),RootPathInfo.Owner,di.LastAccessTimeUtc,di.CreationTimeUtc,di.LastWriteTimeUtc,”);
//
//横穿小路
GetSystemObjects(cancellationToken、di、RootPathInfo.Id、DirectoryType);
//完全相加
MetaDataQueue.CompleteAdding();
ACLQueue.CompleteAdding();
//等待
outputMetaDataTask.Wait();
outputACLTask.Wait();
//将文件发送到Splunk
SplunkExport.CopyFilesToSplunk(outputMetaDataTask.Result、outputACLTask.Result、RootPathInfo.Id);
SmartScanDAO dao=新SmartScanDAO();
RootPathInfo.Size=目录大小;
}
捕捉(操作取消异常cex)
{
RootPathInfo.Status=ScanStatus.Cancelled;
if(scDAO==null)
scDAO=新的SmartScanDAO();
scDAO.ScanStatus(RootPathInfo);
ErrorLogger.LogEvent(cex,RootPathInfo.Id);
}
捕获(例外情况除外)
{
if(RootPathInfo==null)
{
RootPathInfo=新路径信息();
RootPathInfo.Id=路径Id;
}
ErrorLogger.LogEvent(例如RootPathInfo.Id);
RootPathInfo.Status=ScanStatus.Error;
if(scDAO==null)
scDAO=新的SmartScanDAO();
scDAO.ScanStatus(RootPathInfo);
}
}
列表写入输出(字符串路径、SplunkFileType文件类型、BlockingCollection队列)
{
var fileList=新列表();
int filecount=1;
int linecount=0;
int maxlinecount=200000;
字符串头=(fileType.ToString()==SplunkFileType.ACL.ToString()?aclHeader:metaDataHeader);
var filepattern=SplunkExport.getpath(path,fileType.ToString());
string filename=string.Format(filepattern,filecount);
添加(文件名);
while(true)
{
使用(var strm=File.AppendText(文件名))
{