using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Channels; public abstract class Connection : IAsyncDisposable { private readonly CloseAfter _CloseAfter; private readonly AsyncAction _Open; private readonly AsyncAction _Close; protected Connection(AsyncAction? open = null, AsyncAction? close = null, CloseAfter closeAfter = CloseAfter.Error) { _CloseAfter = closeAfter; _Open = open ?? (() => Task.CompletedTask); _Close = close ?? (() => Task.CompletedTask); } protected Connection(CloseAfter closeAfter = CloseAfter.Error) : this(null, null, closeAfter) {} protected async Task CloseAfterError() { if (_CloseAfter.HasFlag(CloseAfter.Error)) await Close(); } protected async Task CloseAfterTransmit() { if (_CloseAfter.HasFlag(CloseAfter.Transmit)) await Close(); } protected async Task CloseAfterReceive() { if (_CloseAfter.HasFlag(CloseAfter.Receive)) await Close(); } public async Task Open() { try { await _Open(); } catch (Exception) { if (_CloseAfter.HasFlag(CloseAfter.Error)) await Close(); throw; } } public async Task Close() { try { await _Close(); } catch { // ignored } } public async ValueTask DisposeAsync() { await Close(); GC.SuppressFinalize(this); } }