mirror of
https://github.com/DarthAffe/OBD.NET.git
synced 2025-12-12 16:58:30 +00:00
Fixed uses of nullable reference types
This commit is contained in:
parent
18b0fec0f2
commit
163f5eb3a3
@ -21,9 +21,7 @@ public class Program
|
|||||||
Console.WriteLine("\nAvailable ports:");
|
Console.WriteLine("\nAvailable ports:");
|
||||||
|
|
||||||
foreach (string port in availablePorts)
|
foreach (string port in availablePorts)
|
||||||
{
|
|
||||||
Console.WriteLine(port);
|
Console.WriteLine(port);
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -33,10 +31,10 @@ public class Program
|
|||||||
using SerialConnection connection = new(comPort);
|
using SerialConnection connection = new(comPort);
|
||||||
using ELM327 dev = new(connection, new OBDConsoleLogger(OBDLogLevel.Debug));
|
using ELM327 dev = new(connection, new OBDConsoleLogger(OBDLogLevel.Debug));
|
||||||
|
|
||||||
dev.SubscribeDataReceived<EngineRPM>((sender, data) => Console.WriteLine("EngineRPM: " + data.Data.Rpm));
|
dev.SubscribeDataReceived<EngineRPM>((_, data) => Console.WriteLine("EngineRPM: " + data.Data.Rpm));
|
||||||
dev.SubscribeDataReceived<EngineFuelRate>((sender, data) => Console.WriteLine("VehicleSpeed: " + data.Data));
|
dev.SubscribeDataReceived<EngineFuelRate>((_, data) => Console.WriteLine("VehicleSpeed: " + data.Data));
|
||||||
|
|
||||||
dev.SubscribeDataReceived<IOBDData>((sender, data) => Console.WriteLine($"PID {data.Data.PID.ToHexString()}: {data.Data}"));
|
dev.SubscribeDataReceived<IOBDData>((_, data) => Console.WriteLine($"PID {data.Data.PID.ToHexString()}: {data.Data}"));
|
||||||
|
|
||||||
dev.Initialize();
|
dev.Initialize();
|
||||||
dev.RequestData<FuelType>();
|
dev.RequestData<FuelType>();
|
||||||
@ -66,18 +64,18 @@ public class Program
|
|||||||
using SerialConnection connection = new(comPort);
|
using SerialConnection connection = new(comPort);
|
||||||
using ELM327 dev = new(connection, new OBDConsoleLogger(OBDLogLevel.Debug));
|
using ELM327 dev = new(connection, new OBDConsoleLogger(OBDLogLevel.Debug));
|
||||||
|
|
||||||
dev.Initialize();
|
await dev.InitializeAsync();
|
||||||
|
|
||||||
EngineRPM engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
EngineRPM? engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
||||||
Console.WriteLine("Data: " + engineRpm.Rpm);
|
Console.WriteLine("Data: " + (engineRpm?.Rpm.ToString() ?? "-"));
|
||||||
|
|
||||||
engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
||||||
Console.WriteLine("Data: " + engineRpm.Rpm);
|
Console.WriteLine("Data: " + (engineRpm?.Rpm.ToString() ?? "-"));
|
||||||
|
|
||||||
VehicleSpeed vehicleSpeed = await dev.RequestDataAsync<VehicleSpeed>();
|
VehicleSpeed? vehicleSpeed = await dev.RequestDataAsync<VehicleSpeed>();
|
||||||
Console.WriteLine("Data: " + vehicleSpeed.Speed);
|
Console.WriteLine("Data: " + (vehicleSpeed?.Speed.ToString() ?? "-"));
|
||||||
|
|
||||||
engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
engineRpm = await dev.RequestDataAsync<EngineRPM>();
|
||||||
Console.WriteLine("Data: " + engineRpm.Rpm);
|
Console.WriteLine("Data: " + (engineRpm?.Rpm.ToString() ?? "-"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,7 +46,6 @@ namespace OBD.NET.Communication
|
|||||||
/// Initializes a new instance of the <see cref="BluetoothSerialConnection"/> class.
|
/// Initializes a new instance of the <see cref="BluetoothSerialConnection"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="deviceName">Name of the _device.</param>
|
/// <param name="deviceName">Name of the _device.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
public BluetoothSerialConnection(string deviceName)
|
public BluetoothSerialConnection(string deviceName)
|
||||||
{
|
{
|
||||||
this._device = deviceName;
|
this._device = deviceName;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@ -28,13 +28,13 @@ public class ATCommand
|
|||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public string Command { get; }
|
public string Command { get; }
|
||||||
public string ExpectedResult { get; }
|
public string? ExpectedResult { get; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
private ATCommand(string command, string expectedResult = null)
|
private ATCommand(string command, string? expectedResult = null)
|
||||||
{
|
{
|
||||||
this.Command = command;
|
this.Command = command;
|
||||||
this.ExpectedResult = expectedResult;
|
this.ExpectedResult = expectedResult;
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#if NET5_0_OR_GREATER
|
#if NET5_0_OR_GREATER
|
||||||
|
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Text;
|
|
||||||
using OBD.NET.Communication.EventArgs;
|
using OBD.NET.Communication.EventArgs;
|
||||||
|
|
||||||
namespace OBD.NET.Communication;
|
namespace OBD.NET.Communication;
|
||||||
@ -12,19 +11,16 @@ public class SerialConnection : ISerialConnection
|
|||||||
|
|
||||||
private readonly SerialPort _serialPort;
|
private readonly SerialPort _serialPort;
|
||||||
|
|
||||||
public bool IsOpen => _serialPort?.IsOpen ?? false;
|
public bool IsOpen => _serialPort.IsOpen;
|
||||||
public bool IsAsync => false;
|
public bool IsAsync => false;
|
||||||
|
|
||||||
private readonly byte[] _readBuffer = new byte[1024];
|
private readonly byte[] _readBuffer = new byte[1024];
|
||||||
private readonly StringBuilder _lineBuffer = new();
|
|
||||||
|
|
||||||
private readonly AutoResetEvent _hasPrompt = new(true);
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
public event EventHandler<DataReceivedEventArgs> DataReceived = delegate { };
|
public event EventHandler<DataReceivedEventArgs>? DataReceived = delegate { };
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -61,7 +57,7 @@ public class SerialConnection : ISerialConnection
|
|||||||
DataReceived?.Invoke(this, new DataReceivedEventArgs(count, _readBuffer));
|
DataReceived?.Invoke(this, new DataReceivedEventArgs(count, _readBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() => _serialPort?.Dispose();
|
public void Dispose() => _serialPort.Dispose();
|
||||||
|
|
||||||
public Task ConnectAsync() => throw new NotSupportedException("Asynchronous operations not supported");
|
public Task ConnectAsync() => throw new NotSupportedException("Asynchronous operations not supported");
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ public class Count : GenericData
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
protected override string Unit => null;
|
protected override string? Unit => null;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public class Degree : GenericData
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
public override string ToString() => (IsFloatingPointValue ? Value.ToString("0.00") : Value.ToString()) + (Unit ?? string.Empty);
|
public override string ToString() => (IsFloatingPointValue ? Value.ToString("0.00") : Value.ToString()) + Unit;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ public class DegreeCelsius : GenericData
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
public override string ToString() => (IsFloatingPointValue ? Value.ToString("0.00") : Value.ToString()) + (Unit ?? string.Empty);
|
public override string ToString() => (IsFloatingPointValue ? Value.ToString("0.00") : Value.ToString()) + Unit;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ public abstract class GenericData
|
|||||||
public double MaxValue { get; }
|
public double MaxValue { get; }
|
||||||
public bool IsFloatingPointValue { get; }
|
public bool IsFloatingPointValue { get; }
|
||||||
|
|
||||||
protected abstract string Unit { get; }
|
protected abstract string? Unit { get; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ public class Ratio : GenericData
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
protected override string Unit => null;
|
protected override string? Unit => null;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ public class CommandResult
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public object Result { get; set; }
|
public object? Result { get; set; }
|
||||||
public AsyncManualResetEvent WaitHandle { get; }
|
public AsyncManualResetEvent WaitHandle { get; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -21,7 +21,7 @@ public class ELM327 : SerialDevice
|
|||||||
|
|
||||||
protected Mode Mode { get; set; } = Mode.ShowCurrentData; //TODO DarthAffe 26.06.2016: Implement different modes
|
protected Mode Mode { get; set; } = Mode.ShowCurrentData; //TODO DarthAffe 26.06.2016: Implement different modes
|
||||||
|
|
||||||
protected string MessageChunk { get; set; }
|
protected string MessageChunk { get; set; } = string.Empty;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -30,13 +30,13 @@ public class ELM327 : SerialDevice
|
|||||||
public delegate void DataReceivedEventHandler<T>(object sender, DataReceivedEventArgs<T> args) where T : IOBDData;
|
public delegate void DataReceivedEventHandler<T>(object sender, DataReceivedEventArgs<T> args) where T : IOBDData;
|
||||||
|
|
||||||
public delegate void RawDataReceivedEventHandler(object sender, RawDataReceivedEventArgs args);
|
public delegate void RawDataReceivedEventHandler(object sender, RawDataReceivedEventArgs args);
|
||||||
public event RawDataReceivedEventHandler RawDataReceived;
|
public event RawDataReceivedEventHandler? RawDataReceived;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public ELM327(ISerialConnection connection, IOBDLogger logger = null)
|
public ELM327(ISerialConnection connection, IOBDLogger? logger = null)
|
||||||
: base(connection, logger: logger)
|
: base(connection, logger: logger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ public class ELM327 : SerialDevice
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual async Task<T> RequestDataAsync<T>()
|
public virtual async Task<T?> RequestDataAsync<T>()
|
||||||
where T : class, IOBDData, new()
|
where T : class, IOBDData, new()
|
||||||
{
|
{
|
||||||
Logger?.WriteLine("Requesting Type " + typeof(T).Name + " ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Requesting Type " + typeof(T).Name + " ...", OBDLogLevel.Debug);
|
||||||
@ -135,9 +135,8 @@ public class ELM327 : SerialDevice
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Requests the data asynchronous and return the data when available
|
/// Requests the data asynchronous and return the data when available
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual async Task<IOBDData> RequestDataAsync(Type type)
|
public virtual async Task<IOBDData?> RequestDataAsync(Type type)
|
||||||
{
|
{
|
||||||
Logger?.WriteLine("Requesting Type " + type.Name + " ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Requesting Type " + type.Name + " ...", OBDLogLevel.Debug);
|
||||||
byte pid = ResolvePid(type);
|
byte pid = ResolvePid(type);
|
||||||
@ -148,7 +147,7 @@ public class ELM327 : SerialDevice
|
|||||||
/// Request data based on a pid
|
/// Request data based on a pid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pid">The pid of the requested data</param>
|
/// <param name="pid">The pid of the requested data</param>
|
||||||
public virtual async Task<object> RequestDataAsync(byte pid)
|
public virtual async Task<object?> RequestDataAsync(byte pid)
|
||||||
{
|
{
|
||||||
Logger?.WriteLine("Requesting PID " + pid.ToString("X2") + " ...", OBDLogLevel.Debug);
|
Logger?.WriteLine("Requesting PID " + pid.ToString("X2") + " ...", OBDLogLevel.Debug);
|
||||||
CommandResult result = SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
|
CommandResult result = SendCommand(((byte)Mode).ToString("X2") + pid.ToString("X2"));
|
||||||
@ -157,10 +156,8 @@ public class ELM327 : SerialDevice
|
|||||||
return result.Result;
|
return result.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override object ProcessMessage(string message)
|
protected override object? ProcessMessage(string message)
|
||||||
{
|
{
|
||||||
if (message == null) return null;
|
|
||||||
|
|
||||||
DateTime timestamp = DateTime.Now;
|
DateTime timestamp = DateTime.Now;
|
||||||
|
|
||||||
RawDataReceived?.Invoke(this, new RawDataReceivedEventArgs(message, timestamp));
|
RawDataReceived?.Invoke(this, new RawDataReceivedEventArgs(message, timestamp));
|
||||||
@ -177,7 +174,7 @@ public class ELM327 : SerialDevice
|
|||||||
else if (message[0] == '1')
|
else if (message[0] == '1')
|
||||||
{
|
{
|
||||||
string fullMessage = MessageChunk + message.Substring(2, message.Length - 2);
|
string fullMessage = MessageChunk + message.Substring(2, message.Length - 2);
|
||||||
MessageChunk = null;
|
MessageChunk = string.Empty;
|
||||||
return ProcessMessage(fullMessage);
|
return ProcessMessage(fullMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,15 +184,15 @@ public class ELM327 : SerialDevice
|
|||||||
if (mode == (byte)Mode)
|
if (mode == (byte)Mode)
|
||||||
{
|
{
|
||||||
byte pid = (byte)message.Substring(2, 2).GetHexVal();
|
byte pid = (byte)message.Substring(2, 2).GetHexVal();
|
||||||
if (DataTypeCache.TryGetValue(pid, out Type dataType))
|
if (DataTypeCache.TryGetValue(pid, out Type? dataType))
|
||||||
{
|
{
|
||||||
IOBDData obdData = (IOBDData)Activator.CreateInstance(dataType);
|
IOBDData obdData = (IOBDData)Activator.CreateInstance(dataType)!;
|
||||||
obdData.Load(message.Substring(4, message.Length - 4));
|
obdData.Load(message.Substring(4, message.Length - 4));
|
||||||
|
|
||||||
if (DataReceivedEventHandlers.TryGetValue(dataType, out IDataEventManager dataEventManager))
|
if (DataReceivedEventHandlers.TryGetValue(dataType, out IDataEventManager? dataEventManager))
|
||||||
dataEventManager.RaiseEvent(this, obdData, timestamp);
|
dataEventManager.RaiseEvent(this, obdData, timestamp);
|
||||||
|
|
||||||
if (DataReceivedEventHandlers.TryGetValue(typeof(IOBDData), out IDataEventManager genericDataEventManager))
|
if (DataReceivedEventHandlers.TryGetValue(typeof(IOBDData), out IDataEventManager? genericDataEventManager))
|
||||||
genericDataEventManager.RaiseEvent(this, obdData, timestamp);
|
genericDataEventManager.RaiseEvent(this, obdData, timestamp);
|
||||||
|
|
||||||
return obdData;
|
return obdData;
|
||||||
@ -223,8 +220,7 @@ public class ELM327 : SerialDevice
|
|||||||
|
|
||||||
protected virtual byte AddToPidCache(Type obdDataType)
|
protected virtual byte AddToPidCache(Type obdDataType)
|
||||||
{
|
{
|
||||||
IOBDData data = (IOBDData)Activator.CreateInstance(obdDataType);
|
if (Activator.CreateInstance(obdDataType) is not IOBDData data) throw new ArgumentException("Has to implement IOBDData", nameof(obdDataType));
|
||||||
if (data == null) throw new ArgumentException("Has to implement IOBDData", nameof(obdDataType));
|
|
||||||
|
|
||||||
byte pid = data.PID;
|
byte pid = data.PID;
|
||||||
|
|
||||||
@ -267,7 +263,7 @@ public class ELM327 : SerialDevice
|
|||||||
|
|
||||||
public void SubscribeDataReceived<T>(DataReceivedEventHandler<T> eventHandler) where T : IOBDData
|
public void SubscribeDataReceived<T>(DataReceivedEventHandler<T> eventHandler) where T : IOBDData
|
||||||
{
|
{
|
||||||
if (!DataReceivedEventHandlers.TryGetValue(typeof(T), out IDataEventManager eventManager))
|
if (!DataReceivedEventHandlers.TryGetValue(typeof(T), out IDataEventManager? eventManager))
|
||||||
DataReceivedEventHandlers.Add(typeof(T), (eventManager = new GenericDataEventManager<T>()));
|
DataReceivedEventHandlers.Add(typeof(T), (eventManager = new GenericDataEventManager<T>()));
|
||||||
|
|
||||||
((GenericDataEventManager<T>)eventManager).DataReceived += eventHandler;
|
((GenericDataEventManager<T>)eventManager).DataReceived += eventHandler;
|
||||||
@ -275,7 +271,7 @@ public class ELM327 : SerialDevice
|
|||||||
|
|
||||||
public void UnsubscribeDataReceived<T>(DataReceivedEventHandler<T> eventHandler) where T : IOBDData
|
public void UnsubscribeDataReceived<T>(DataReceivedEventHandler<T> eventHandler) where T : IOBDData
|
||||||
{
|
{
|
||||||
if (DataReceivedEventHandlers.TryGetValue(typeof(T), out IDataEventManager eventManager))
|
if (DataReceivedEventHandlers.TryGetValue(typeof(T), out IDataEventManager? eventManager))
|
||||||
((GenericDataEventManager<T>)eventManager).DataReceived -= eventHandler;
|
((GenericDataEventManager<T>)eventManager).DataReceived -= eventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ public class STN1170 : ELM327 // Fully compatible device
|
|||||||
{
|
{
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public STN1170(ISerialConnection connection, IOBDLogger logger = null)
|
public STN1170(ISerialConnection connection, IOBDLogger? logger = null)
|
||||||
: base(connection, logger)
|
: base(connection, logger)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|||||||
@ -17,16 +17,16 @@ public abstract class SerialDevice : IDisposable
|
|||||||
private readonly BlockingCollection<QueuedCommand> _commandQueue = new();
|
private readonly BlockingCollection<QueuedCommand> _commandQueue = new();
|
||||||
private readonly StringBuilder _lineBuffer = new();
|
private readonly StringBuilder _lineBuffer = new();
|
||||||
private readonly AutoResetEvent _commandFinishedEvent = new(false);
|
private readonly AutoResetEvent _commandFinishedEvent = new(false);
|
||||||
private Task _commandWorkerTask;
|
private Task? _commandWorkerTask;
|
||||||
private CancellationTokenSource _commandCancellationToken;
|
private CancellationTokenSource? _commandCancellationToken;
|
||||||
|
|
||||||
private volatile int _queueSize = 0;
|
private volatile int _queueSize = 0;
|
||||||
private readonly ManualResetEvent _queueEmptyEvent = new(true);
|
private readonly ManualResetEvent _queueEmptyEvent = new(true);
|
||||||
|
|
||||||
public int QueueSize => _queueSize;
|
public int QueueSize => _queueSize;
|
||||||
|
|
||||||
protected QueuedCommand CurrentCommand;
|
protected QueuedCommand? CurrentCommand;
|
||||||
protected IOBDLogger Logger { get; }
|
protected IOBDLogger? Logger { get; }
|
||||||
protected ISerialConnection Connection { get; }
|
protected ISerialConnection Connection { get; }
|
||||||
protected char Terminator { get; set; }
|
protected char Terminator { get; set; }
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
/// <param name="connection">connection.</param>
|
/// <param name="connection">connection.</param>
|
||||||
/// <param name="terminator">terminator used for terminating the command message</param>
|
/// <param name="terminator">terminator used for terminating the command message</param>
|
||||||
/// <param name="logger">logger instance</param>
|
/// <param name="logger">logger instance</param>
|
||||||
protected SerialDevice(ISerialConnection connection, char terminator = '\r', IOBDLogger logger = null)
|
protected SerialDevice(ISerialConnection connection, char terminator = '\r', IOBDLogger? logger = null)
|
||||||
{
|
{
|
||||||
this.Connection = connection;
|
this.Connection = connection;
|
||||||
this.Terminator = terminator;
|
this.Terminator = terminator;
|
||||||
@ -88,8 +88,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
_commandCancellationToken = new CancellationTokenSource();
|
_commandCancellationToken = new CancellationTokenSource();
|
||||||
_commandWorkerTask = Task.Factory.StartNew(CommandWorker);
|
_commandWorkerTask = Task.Factory.StartNew(CommandWorker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends the command.
|
/// Sends the command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -105,7 +104,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
|
|
||||||
QueuedCommand cmd = new(command);
|
QueuedCommand cmd = new(command);
|
||||||
_queueEmptyEvent.Reset();
|
_queueEmptyEvent.Reset();
|
||||||
_queueSize++;
|
Interlocked.Increment(ref _queueSize);
|
||||||
_commandQueue.Add(cmd);
|
_commandQueue.Add(cmd);
|
||||||
|
|
||||||
return cmd.CommandResult;
|
return cmd.CommandResult;
|
||||||
@ -131,7 +130,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The sender.</param>
|
/// <param name="sender">The sender.</param>
|
||||||
/// <param name="e">The <see cref="DataReceivedEventArgs"/> instance containing the event data.</param>
|
/// <param name="e">The <see cref="DataReceivedEventArgs"/> instance containing the event data.</param>
|
||||||
private void OnDataReceived(object sender, DataReceivedEventArgs e)
|
private void OnDataReceived(object? sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < e.Count; i++)
|
for (int i = 0; i < e.Count; i++)
|
||||||
{
|
{
|
||||||
@ -143,7 +142,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
CurrentCommand.CommandResult.WaitHandle.Set();
|
CurrentCommand?.CommandResult.WaitHandle.Set();
|
||||||
_commandFinishedEvent.Set();
|
_commandFinishedEvent.Set();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -178,8 +177,9 @@ public abstract class SerialDevice : IDisposable
|
|||||||
/// <param name="message">The message.</param>
|
/// <param name="message">The message.</param>
|
||||||
private void InternalProcessMessage(string message)
|
private void InternalProcessMessage(string message)
|
||||||
{
|
{
|
||||||
object data = ProcessMessage(message);
|
object? data = ProcessMessage(message);
|
||||||
CurrentCommand.CommandResult.Result = data;
|
if (CurrentCommand != null)
|
||||||
|
CurrentCommand.CommandResult.Result = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -187,13 +187,15 @@ public abstract class SerialDevice : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">message received</param>
|
/// <param name="message">message received</param>
|
||||||
/// <returns>result data</returns>
|
/// <returns>result data</returns>
|
||||||
protected abstract object ProcessMessage(string message);
|
protected abstract object? ProcessMessage(string message);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Worker method for sending commands
|
/// Worker method for sending commands
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async void CommandWorker()
|
private async void CommandWorker()
|
||||||
{
|
{
|
||||||
|
if (_commandCancellationToken == null) return;
|
||||||
|
|
||||||
CancellationToken cancellationToken = _commandCancellationToken.Token;
|
CancellationToken cancellationToken = _commandCancellationToken.Token;
|
||||||
|
|
||||||
while (!_commandCancellationToken.IsCancellationRequested)
|
while (!_commandCancellationToken.IsCancellationRequested)
|
||||||
@ -207,13 +209,14 @@ public abstract class SerialDevice : IDisposable
|
|||||||
{
|
{
|
||||||
if (_commandQueue.TryTake(out CurrentCommand, 10, cancellationToken))
|
if (_commandQueue.TryTake(out CurrentCommand, 10, cancellationToken))
|
||||||
{
|
{
|
||||||
_queueSize--;
|
Interlocked.Decrement(ref _queueSize);
|
||||||
|
|
||||||
Logger?.WriteLine("Writing Command: '" + CurrentCommand.CommandText.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
|
Logger?.WriteLine("Writing Command: '" + CurrentCommand.CommandText.Replace('\r', '\'') + "'", OBDLogLevel.Verbose);
|
||||||
|
|
||||||
if (Connection.IsAsync)
|
if (Connection.IsAsync)
|
||||||
await Connection.WriteAsync(Encoding.ASCII.GetBytes(CurrentCommand.CommandText));
|
await Connection.WriteAsync(Encoding.ASCII.GetBytes(CurrentCommand.CommandText));
|
||||||
else
|
else
|
||||||
|
// ReSharper disable once MethodHasAsyncOverload
|
||||||
Connection.Write(Encoding.ASCII.GetBytes(CurrentCommand.CommandText));
|
Connection.Write(Encoding.ASCII.GetBytes(CurrentCommand.CommandText));
|
||||||
|
|
||||||
// wait for command to finish or command canceled
|
// wait for command to finish or command canceled
|
||||||
@ -233,7 +236,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
|
|
||||||
public void WaitQueue() => _queueEmptyEvent.WaitOne();
|
public void WaitQueue() => _queueEmptyEvent.WaitOne();
|
||||||
|
|
||||||
public async Task WaitQueueAsync() => await Task.Run(() => WaitQueue());
|
public async Task WaitQueueAsync() => await Task.Run(WaitQueue);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
@ -243,7 +246,7 @@ public abstract class SerialDevice : IDisposable
|
|||||||
_commandQueue.CompleteAdding();
|
_commandQueue.CompleteAdding();
|
||||||
_commandCancellationToken?.Cancel();
|
_commandCancellationToken?.Cancel();
|
||||||
_commandWorkerTask?.Wait();
|
_commandWorkerTask?.Wait();
|
||||||
Connection?.Dispose();
|
Connection.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public class GenericDataEventManager<T> : IDataEventManager
|
|||||||
{
|
{
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
internal event ELM327.DataReceivedEventHandler<T> DataReceived;
|
internal event ELM327.DataReceivedEventHandler<T>? DataReceived;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ public class CalculatedEngineLoad : AbstractOBDData
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public Percent Load => new(A / 2.55, 0, 100);
|
public new Percent Load => new(A / 2.55, 0, 100);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ public class AbsoluteLoadValue : AbstractOBDData
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
public Percent Load => new(((256 * A) + B) / 2.55, 0, 25700);
|
public new Percent Load => new(((256 * A) + B) / 2.55, 0, 25700);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public abstract class AbstractOBDData : IOBDData
|
|||||||
public byte PID { get; }
|
public byte PID { get; }
|
||||||
private readonly int _length;
|
private readonly int _length;
|
||||||
|
|
||||||
private byte[] _rawData;
|
private byte[] _rawData = Array.Empty<byte>();
|
||||||
public byte[] RawData
|
public byte[] RawData
|
||||||
{
|
{
|
||||||
get => _rawData;
|
get => _rawData;
|
||||||
|
|||||||
@ -26,8 +26,8 @@ public class AsyncManualResetEvent
|
|||||||
public void Set()
|
public void Set()
|
||||||
{
|
{
|
||||||
TaskCompletionSource<bool> tcs = _tcs;
|
TaskCompletionSource<bool> tcs = _tcs;
|
||||||
Task.Factory.StartNew(s => ((TaskCompletionSource<bool>)s).TrySetResult(true),
|
Task.Factory.StartNew(s => ((TaskCompletionSource<bool>)s!).TrySetResult(true),
|
||||||
tcs, CancellationToken.None, TaskCreationOptions.PreferFairness, TaskScheduler.Default);
|
tcs, CancellationToken.None, TaskCreationOptions.PreferFairness, TaskScheduler.Default);
|
||||||
|
|
||||||
tcs.Task.Wait();
|
tcs.Task.Wait();
|
||||||
}
|
}
|
||||||
@ -40,8 +40,7 @@ public class AsyncManualResetEvent
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
TaskCompletionSource<bool> tcs = _tcs;
|
TaskCompletionSource<bool> tcs = _tcs;
|
||||||
if (!tcs.Task.IsCompleted ||
|
if (!tcs.Task.IsCompleted || (Interlocked.CompareExchange(ref _tcs, new TaskCompletionSource<bool>(), tcs) == tcs))
|
||||||
(Interlocked.CompareExchange(ref _tcs, new TaskCompletionSource<bool>(), tcs) == tcs))
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user