[Timeout(2000)] // We abort the test after timeout. This tests the blocking behavior in ReadAsync and the test will fail if ReadAsync blocks.
        public async Task WriteAsync()
        {
            using (var serialPortStreamWrite = new SerialPortStream("COM1", 9600, 8, Parity.None, StopBits.One))
                using (var serialPortStreamRead = new SerialPortStream("COM2", 9600, 8, Parity.None, StopBits.One))
                {
                    serialPortStreamWrite.Open();
                    serialPortStreamRead.Open();

                    var buffer   = new byte[1024];
                    var readTask = Task.Run(async() => await serialPortStreamRead.ReadAsync(buffer, 0, buffer.Length));

                    var bytes = new byte[] { 0x01, 0x02, 0x03 };
                    await serialPortStreamWrite.WriteAsync(bytes, 0, bytes.Length);

                    await serialPortStreamWrite.FlushAsync();

                    // ReadAsync blocks here even if something gets written and flushed to the underlying COM device.
                    // Fails for netcoreapp3.1, works with net472
                    await readTask;

                    Assert.That(buffer[0], Is.EqualTo(0x01));
                    Assert.That(buffer[1], Is.EqualTo(0x02));
                    Assert.That(buffer[2], Is.EqualTo(0x03));
                }
        }
        static async Task Main(string[] args)
        {
            Console.WriteLine("Start");

            using (var serialPortStreamWrite = new SerialPortStream("COM1", 9600, 8, Parity.None, StopBits.One))
                using (var serialPortStreamRead = new SerialPortStream("COM2", 9600, 8, Parity.None, StopBits.One))
                {
                    serialPortStreamWrite.Open();
                    serialPortStreamRead.Open();

                    Console.WriteLine("Serial Port Opened");

                    var buffer   = new byte[1024];
                    var readTask = Task.Run(async() => await serialPortStreamRead.ReadAsync(buffer, 0, buffer.Length));

                    Console.WriteLine("Wait for write. Enter any key.");
                    Console.ReadKey();


                    var bytes = new byte[] { 0x01, 0x02, 0x03 };

                    Console.WriteLine("Write started");
                    await serialPortStreamWrite.WriteAsync(bytes, 0, bytes.Length);

                    await serialPortStreamWrite.FlushAsync();

                    Console.WriteLine("Write finished");


                    Console.WriteLine("Awaiting read...");

                    await readTask;

                    Console.WriteLine($"Buffer: {buffer[0]}, {buffer[1]}, {buffer[2]}");

                    Console.WriteLine("Finished.");
                }
        }
示例#3
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            var options = _options.Value;

            _logger.LogInformation("Opening {SerialPort}", options.Port);

            using (var port = new SerialPortStream(options.Port, options.Baud))
            {
                port.Open();

                // Clear Status
                var cls = Encoding.ASCII.GetBytes("*CLS\n");
                await port.WriteAsync(cls, 0, cls.Length);

                // §3.5.10
                var formatPacked = Encoding.ASCII.GetBytes("FORMat PACKed\n");
                await port.WriteAsync(formatPacked, 0, formatPacked.Length);

                // §3.5.17
                var lterEoi = Encoding.ASCII.GetBytes("SYSTem:COMMunicate:GPIB:LTERminator EOI\n");
                await port.WriteAsync(lterEoi, 0, lterEoi.Length);

                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        await _wait.WaitAsync(cancellationToken);
                    }
                    catch (OperationCanceledException)
                    {
                    }

                    if (_queue.TryDequeue(out var item))
                    {
                        if (item.CancellationToken.IsCancellationRequested)
                        {
                            continue;
                        }

                        _logger.LogDebug("Sending {Request}", Encoding.ASCII.GetString(item.Request));

                        await port.WriteAsync(item.Request, 0, item.Request.Length, cancellationToken);

                        await port.FlushAsync(cancellationToken);

                        if (item.ExpectResponse)
                        {
                            var buffer = ArrayPool <byte> .Shared.Rent(1024);

                            var offset = 0;

                            try
                            {
                                var length = -1;

                                while (length == -1 || offset < length)
                                {
                                    var oldOffset = offset;
                                    var increased = await port.ReadAsync(buffer, offset, buffer.Length - offset, cancellationToken);

                                    offset += increased;

                                    if (offset > 0 && buffer[offset] == '#' && BlockData.TryDecodeLength(buffer.AsSpan().Slice(0, offset), out var decodedLength))
                                    {
                                        length = decodedLength;
                                    }
                                    else
                                    {
                                        var relativeIndex = buffer.AsSpan().Slice(oldOffset, increased).IndexOf((byte)'\n');

                                        if (relativeIndex >= 0)
                                        {
                                            length = oldOffset + relativeIndex + 1;
                                        }
                                    }
                                }

                                var response = buffer.AsSpan().Slice(0, length).ToArray();

                                _logger.LogDebug("Received {ResponseBytes} bytes: {Response}", response.Length, Encoding.ASCII.GetString(response));

                                item.TaskCompletionSource.SetResult(response);
                            }
                            finally
                            {
                                ArrayPool <byte> .Shared.Return(buffer);
                            }
                        }
                        else
                        {
                            item.TaskCompletionSource.SetResult(null);
                        }
                    }
                }

                port.Close();
            }
        }
 public Task FlushAsync(CancellationToken cancellationToken) =>
 _serialPort?.FlushAsync(cancellationToken);