Innovenergy_trunk/csharp/Lib/Protocols/Modbus/Channels/ConnectionChannel.cs

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();
}