Beispiel #1
0
        static Task KeyHandlingAsync(Configuration config, CancellationTokenSource cancelSource, SerialWrapper serial)
        => Task.Run(() =>
        {
            Console.WriteLine("Ctrl-C to quit");
            Console.WriteLine("Ctrl-X to clear screen");
            if (config.IsLogging)
            {
                Console.WriteLine("Ctrl-Space to start logging to a new log file");
            }
            Console.WriteLine();

            while (!cancelSource.IsCancellationRequested)
            {
                var keyInfo = Console.ReadKey(true);
                // Application control
                if (keyInfo.Modifiers == ConsoleModifiers.Control)
                {
                    switch (keyInfo.Key)
                    {
                    case ConsoleKey.C:
                        cancelSource.Cancel();
                        break;

                    case ConsoleKey.X:
                        Console.Clear();
                        Console.WriteLine(GenerateHeader(config));
                        Console.WriteLine("Ctrl-C to quit");
                        Console.WriteLine("Ctrl-X to clear screen");
                        if (config.IsLogging)
                        {
                            Console.WriteLine("Ctrl-Space to start logging to a new log file");
                        }
                        Console.WriteLine();
                        break;

                    case ConsoleKey.Spacebar:
                        if (config.IsLogging)
                        {
                            config.Logger.RollLog();
                        }
                        break;
                    }
                }
                // Text input
                else if (config.AllowKeyEntry)
                {
                    var data = Encoding.ASCII.GetBytes(new[] { keyInfo.KeyChar });
                    serial.WriteAsync(data, 0, data.Length);
                }
            }
        });
Beispiel #2
0
        static Task SerialReadAsync(Configuration config, DataBuffer dataQueue, CancellationToken cancelToken, SerialWrapper serial)
        {
            return(Task.Run(async() =>
            {
                try
                {
                    // Try open the port. Only one try is necessary
                    if (!serial.Open())
                    {
                        return;
                    }

                    var isReadValid = true;
                    while (isReadValid && !cancelToken.IsCancellationRequested)
                    {
                        var retries = 10;
                        do
                        {
                            var bytesRead = await serial.ReadAsync(cancelToken);
                            if (bytesRead == 0)
                            {
                                // ReadAsync terminated because we cancelled a task.
                                // Just jump out
                                if (cancelToken.IsCancellationRequested)
                                {
                                    break;
                                }

                                Console.WriteLine($"{Environment.NewLine}WARNING: Cannot read from port {config.COMPort}. Retrying...");
                                serial.Close();
                                await Task.Delay(5000, cancelToken);

                                // Try re-open the serial port, as many times as we can
                                while (!serial.Open() && --retries > 0)
                                {
                                    await Task.Delay(2000, cancelToken);
                                }
                            }
                        } while (retries > 0 && !isReadValid);
                    }
                }
                catch (OperationCanceledException)
                {
                    // Ignore cancellations
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"{Environment.NewLine}{Environment.NewLine}ERROR: {ex.Message}{Environment.NewLine}{Environment.NewLine}{ex}");
                }
            }));
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            Console.TreatControlCAsInput = true;

            if (ParseCommandLine(args, out var config))
            {
                string exitMsg = string.Empty;
                using (config.Logger = new LineLogger(config))
                {
                    var header = GenerateHeader(config);

                    if (config.IsLogging)
                    {
                        config.Logger.Header = header;
                    }
                    Console.WriteLine(header);

                    var dataQueue    = new DataBuffer(BUFFER_SIZE * 10);
                    var cancelSource = new CancellationTokenSource();

                    using (var serial = new SerialWrapper(config, dataQueue, BUFFER_SIZE / 2))
                    {
                        try
                        {
                            var taskList = new List <Tuple <string, Task> >()
                            {
                                new Tuple <string, Task>("Serial read", SerialReadAsync(config, dataQueue, cancelSource.Token, serial)),
                                new Tuple <string, Task>("Key handling", KeyHandlingAsync(config, cancelSource, serial)),
                                new Tuple <string, Task>("Log write", LogWriteAsync(config, dataQueue, cancelSource.Token))
                            };

                            // Wait for any of the tasks to end
                            var index = Task.WaitAny(taskList.Select(t => t.Item2).ToArray());

                            // Cancel the other tasks
                            cancelSource.Cancel();

                            // Wait for the logger to complete (it must be the last task!)
                            Task.WaitAll(taskList.Select(t => t.Item2).Last());
                            exitMsg = $"{Environment.NewLine}Exit: {taskList[index].Item1}";
                        }
                        catch (OperationCanceledException)
                        {
                            // Ignore cancellations
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"{Environment.NewLine}{Environment.NewLine}ERROR: {ex.Message}{Environment.NewLine}{Environment.NewLine}{ex}");
                        }
                    }
                }

                if (!string.IsNullOrEmpty(exitMsg))
                {
                    Console.WriteLine(exitMsg);
                }
            }
            else
            {
                Environment.ExitCode = 1;
            }
        }