コード例 #1
0
        private async Task _BackgroundRunner(CancellationToken ct)
        {
            _Accumulator.InfosChanged += (sender, infos) =>
            {
                var ordered = infos.OrderByDescending(x => x.TotalDamage);
                var items   = ordered.Select(i => new DamageDisplayList.DamageDisplayData
                {
                    Name              = i.Name,
                    Damage            = i.TotalDamage,
                    DamageRatio       = (100.0 / ordered.First().TotalDamage) * i.TotalDamage,
                    DamageRatioNormal = (100.0 / ordered.First().TotalDamage) * i.TotalDamage,
                    MaxHitDamage      = i.MaxHitDamage,
                    MaxHitName        = $"Id: {i.MaxHitAction}"
                });

                Dispatcher.Invoke(() =>
                {
                    _DamageDisplayList.Items.Clear();
                    foreach (var i in items)
                    {
                        _DamageDisplayList.Items.Add(i);
                    }
                    _DamageDispalyListState = DamageDispalyListState.Visible;
                });
            };

            // TODO: this should probably be done in a better way.
            // at the moment if anything goes wrong the system will
            // reset the accumulator and start again, ~better than a crash?~
            while (true)
            {
                ct.ThrowIfCancellationRequested();

                // wait for file to show up
                var logFile = _GetLatestLogFile(_DamageDumpFolder);
                if (logFile == null)
                {
                    await Task.Delay(1000, ct);

                    continue;
                }

                try
                {
                    Dispatcher.Invoke(() => _DamageDispalyListState = DamageDispalyListState.Loading);

                    var watcher = new LogFileWatcher();
                    watcher.OnNewEntries += async(sender, entries) =>
                    {
                        await _BackgroundSemaphore.WaitAsync();

                        try
                        {
                            _Accumulator.ProcessEntries(entries);
                        }
                        finally
                        {
                            _BackgroundSemaphore.Release();
                        }
                    };

                    using (var fsWatcher = new FileSystemWatcher())
                    {
                        fsWatcher.Path = _DamageDumpFolder;

                        var fsWatcherSource = new CancellationTokenSource();
                        void OnFsChanged(object source, object _)
                        {
                            if (_GetLatestLogFile(_DamageDumpFolder) != logFile)
                            {
                                fsWatcherSource.Cancel();
                            }
                        }

                        fsWatcher.Created += OnFsChanged;
                        fsWatcher.Deleted += OnFsChanged;
                        fsWatcher.Changed += OnFsChanged;
                        fsWatcher.Renamed += OnFsChanged;

                        fsWatcher.EnableRaisingEvents = true;

                        await watcher.RunAsync(logFile, CancellationTokenSource.CreateLinkedTokenSource(ct, fsWatcherSource.Token).Token);
                    }
                }
                catch (OperationCanceledException)
                {
                    // this exception does not mean anything as there are multiple
                    // cancellation tokens that could have caused it, the function however
                    // only cancels to one specific token and that is handled separately
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Exception in log file watcher loop -> {ex.Message}");
                }
                finally
                {
                    await _ResetAccumulator();

                    Dispatcher.Invoke(() => _DamageDispalyListState = DamageDispalyListState.Waiting);
                }
            }
        }
コード例 #2
0
        static void Main(string[] args)
        {
            Outputer("Starting watcher process..");

            // Read configuration
            var configPath = args[0];

            Outputer($"Loading config path from {configPath}");
            var configText = File.ReadAllText(configPath);
            var config     = JsonConvert.DeserializeObject <Configuration>(configText);

            // TODO: Set up logs
            if (config.Etw.Any())
            {
                Outputer($"Configuring ETW providers...");
                var etwWatcher = new EtwWatcher(Outputer);
                foreach (var etwConfiguration in config.Etw)
                {
                    Outputer($"Adding Provider: {etwConfiguration.ProviderName}");
                    etwWatcher.Watch(etwConfiguration.ProviderName);
                }

                Task.Run(() => etwWatcher.StartListening());
            }

            if (config.EventLogs.Any())
            {
                Outputer($"Configuring EventLogs...");
                foreach (var eventLog in config.EventLogs)
                {
                    Outputer($"Adding EventLog: {eventLog.LogName}");
                    Task.Run(() =>
                    {
                        var eventLogWatcher = new EventLogWatcher(Outputer, eventLog.Source);
                        eventLogWatcher.Watch(eventLog.LogName);
                    });
                }
            }

            if (config.LogFiles.Any())
            {
                Outputer("Configuring Logs...");
                foreach (var logFile in config.LogFiles)
                {
                    Outputer($"Adding Logs: {logFile.Location}");
                    Task.Run(() =>
                    {
                        var logFileWatcher = new LogFileWatcher(Outputer);
                        logFileWatcher.Watch(logFile.Location);
                    });
                }
            }

            // Watch services
            Outputer($"Starting services");
            IServiceWatcher serviceWatcher = new PollingServiceWatcher();

            serviceWatcher.StartServices(config.Services, Crash);

            Thread.Sleep(Timeout.Infinite);
        }