82 lines
2.1 KiB
C#
82 lines
2.1 KiB
C#
namespace InnovEnergy.Lib.Protocols.Modbus.Channels;
|
|
|
|
public abstract class ConnectionChannel<T> : Channel, IDisposable
|
|
{
|
|
private readonly Func<Exception, Boolean> _CloseAfterException ;
|
|
private readonly Boolean _CloseAfterSuccessfulRead ;
|
|
private readonly Boolean _CloseAfterSuccessfulWrite ;
|
|
|
|
protected abstract T Open();
|
|
protected abstract void Close(T connection);
|
|
|
|
protected abstract IReadOnlyList<Byte> Read (T connection, Int32 nBytes);
|
|
protected abstract void Write(T connection, IReadOnlyList<Byte> data);
|
|
|
|
private T? _Connection;
|
|
|
|
protected ConnectionChannel(Boolean closeAfterSuccessfulRead = false,
|
|
Boolean closeAfterSuccessfulWrite = false,
|
|
Func<Exception, Boolean>? closeAfterException = null)
|
|
{
|
|
_CloseAfterSuccessfulRead = closeAfterSuccessfulRead;
|
|
_CloseAfterSuccessfulWrite = closeAfterSuccessfulWrite;
|
|
_CloseAfterException = closeAfterException ?? (_ => true);
|
|
}
|
|
|
|
public override IReadOnlyList<Byte> Read(Int32 nBytes)
|
|
{
|
|
try
|
|
{
|
|
return Read(Connection, nBytes);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (_CloseAfterException(e))
|
|
Close();
|
|
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
if (_CloseAfterSuccessfulRead)
|
|
Close();
|
|
}
|
|
}
|
|
|
|
|
|
public override void Write(IReadOnlyList<Byte> data)
|
|
{
|
|
try
|
|
{
|
|
Write(Connection, data);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (_CloseAfterException(e))
|
|
Close();
|
|
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
if (_CloseAfterSuccessfulWrite)
|
|
Close();
|
|
}
|
|
}
|
|
|
|
|
|
private T Connection => _Connection ??= Open();
|
|
|
|
|
|
private void Close()
|
|
{
|
|
if (_Connection is null)
|
|
return;
|
|
|
|
Close(_Connection);
|
|
_Connection = default;
|
|
}
|
|
|
|
|
|
public void Dispose() => Close();
|
|
} |