private static IEnumerable <ErrorInfoAdapter> GetErrorsFromUnparsed(string plogFilename, out string solutionName) { var plogTable = new DataTable(); var solutionPathsTable = new DataTable(); DataTableUtils.CreatePVSDataTable(plogTable, solutionPathsTable, plogTable.DefaultView); var plogSet = new DataSet(); plogSet.Tables.Add(solutionPathsTable); plogSet.Tables.Add(plogTable); var signaller = new ManualResetEventSlim(false); try { var tasksQueue = new ConcurrentQueue <Task <IEnumerable <ErrorInfo> > >(); Exception processingException = null; var processingThread = new Thread(() => { try { while (true) { Task <IEnumerable <ErrorInfo> > currentTask; while (tasksQueue.TryDequeue(out currentTask)) { foreach (var error in currentTask.Result) { DataTableUtils.AppendErrorInfoToDataTable(plogTable, error); } } if (signaller.IsSet && tasksQueue.Count == 0) { return; } Thread.Sleep(1000); } } catch (Exception e) { Volatile.Write <Exception>(ref processingException, e); } }); processingThread.Start(); const int linesToRead = 10000; const int maxTasksCount = 1000000 / linesToRead; //will consume approximately 1GB of memory StringBuilder totalLinesCache = new StringBuilder(linesToRead * 350); //we assume that an average PVS-Studio output line is 350 chars long IList <String> preprocessedFilesDependencies; Func <bool> isProcessingExceptionPresent = () => Volatile.Read <Exception>(ref processingException) != null; using (StreamReader logfileStream = new StreamReader(plogFilename)) { String currentLine; int linesRead = 0; bool isEncoded = false; while (true) { if (isProcessingExceptionPresent()) { break; } currentLine = logfileStream.ReadLine(); if (currentLine == null || linesRead >= linesToRead) { linesRead = 0; var linesText = totalLinesCache.ToString(); totalLinesCache.Clear(); Encoding currentIncodingLocal = logfileStream.CurrentEncoding; bool isIncodedLocal = isEncoded; var errorsTask = new Task <IEnumerable <ErrorInfo> >(() => ErrorInfo.ProcessAnalyzerOutput(String.Empty, String.Empty, String.Empty, linesText, isIncodedLocal, currentIncodingLocal, null, out preprocessedFilesDependencies, String.Empty)); errorsTask.Start(); tasksQueue.Enqueue(errorsTask); while (!isProcessingExceptionPresent() && tasksQueue.Count >= maxTasksCount) { Thread.Sleep(1000); } if (currentLine == null) { signaller.Set(); break; } } if (String.IsNullOrWhiteSpace(currentLine) || currentLine.StartsWith("#")) { continue; } if (currentLine.StartsWith(CppAnalyzerDecoder.EncodeMarker)) { isEncoded = true; continue; } totalLinesCache.Append(currentLine + Environment.NewLine); linesRead++; } } processingThread.Join(); if (isProcessingExceptionPresent()) { throw Volatile.Read <Exception>(ref processingException); } } finally { signaller.Set(); } return(GetErrorsFromXml(out solutionName, plogSet.GetXml())); }