Ejemplo n.º 1
0
        private async Task RunProgramAsync(string logPath, int numberOfParsers, CancellationTokenSource ctSource)
        {
            WriteLog(LogEventLevel.Information, $"Starting to process EQ Log file: {logPath}");
            _eqJob = CreateJobProcessor(numberOfParsers);
            _eqJob.CancelSource = ctSource;

            // Get started waiting for user input
            // When the user quits, then cancel our CTS (which will cause our JobTask to be cancelled)
            var consoleTask = GetConsoleUserInputAsync(ctSource.Token);
            var ctComplete  = consoleTask.ContinueWith(_ => ctSource.Cancel(), TaskContinuationOptions.OnlyOnRanToCompletion);
            // var ctContinue = consoleTask.ContinueWith(_ => { }); // Empty task to await upon

            // Start the JobProcessor, which will read from the log file continuously, parse the lines and add them to the EQBattle
            // When it's done, show the summary
            var jobTask = _eqJob.StartProcessingJobAsync(logPath, _eqBattle);
            var jtError = jobTask.ContinueWith(_ => Log.Error(_.Exception, $"JobTask Error"), TaskContinuationOptions.OnlyOnFaulted);

            // Either the log file wasn't found, or we finished reading the log file. It either case,
            // we need to cancel the 'consoleTask' so we don't wait for the user when we know we're done.
            var jtNotCancelled = jobTask.ContinueWith(_ => ctSource.Cancel(), TaskContinuationOptions.NotOnCanceled);

            // When everything completed successfully (which doesn't reall happen) or cancelled (which is the normal path), show the final status
            var jtComplete = jobTask.ContinueWith(_ => ShowBattleSummary(), TaskContinuationOptions.NotOnFaulted);

            ConcurrentBag <Task> tasksToWaitFor = new ConcurrentBag <Task>();

            try
            {
                // Wait for everything to finish.
                // await Task.WhenAll(ctComplete, ctContinue, jtError, jtNotCancelled, jtComplete);
                // await ctContinue;
                // ctSource.CancelAfter(7*1000);

                await Task.WhenAll(consoleTask, jobTask);

                tasksToWaitFor.Add(jtNotCancelled);
                tasksToWaitFor.Add(jtComplete);
            }
            // catch (TaskCanceledException)
            // {
            //     WriteMessage($"{ex.GetType().Name} - {ex.Message}");
            // }
            catch (OperationCanceledException)
            {
                Log.Information("Program OperationCanceledException");

                if (jobTask.IsCanceled)
                {
                    tasksToWaitFor.Add(jtComplete);
                }
            }
            catch (Exception ex)
            {
                Log.Warning(ex, $"Program Exception");
                WriteMessage($"ERROR: {ex.Message}");

                if (jobTask.IsFaulted)
                {
                    tasksToWaitFor.Add(jtNotCancelled);
                    tasksToWaitFor.Add(jtError);
                }
            }
            finally
            {
                Log.Verbose("Program Finally Block");
                // await Task.WhenAny(jtNotCancelled, jtComplete);
                // await Task.WhenAny(jtError, jtComplete);
                // await jtComplete;
                await Task.WhenAll(tasksToWaitFor);

                DumpTaskInfo(consoleTask, "consoleTask");
                // DumpTaskInfo(ctComplete, "ctComplete");
                // DumpTaskInfo(ctContinue, "ctContinue");
                DumpTaskInfo(jobTask, "jobTask");
                DumpTaskInfo(jtError, "jtError");
                DumpTaskInfo(jtNotCancelled, "jtNotCancelled");
                DumpTaskInfo(jtComplete, "jtComplete");
            }
        }