using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Plane.Communication { /// /// 组合多个潜在的连接。 /// public class CompositeConnection : IConnection { private List _candidateConnections; public CompositeConnection(params IConnection[] candidateConnections) { _candidateConnections = new List(candidateConnections); } public event EventHandler ExceptionThrown; public int BytesToRead() { int result; for (int i = 0; i < _candidateConnections.Count; i++) { if (_candidateConnections[i].IsOpen) { try { result = _candidateConnections[i].BytesToRead(); if (result != 0) { return result; } } catch (Exception ex) { Debug.WriteLine(ex); ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex)); } } } return 0; } public bool IsOpen { get { return _candidateConnections.Any(c => c.IsOpen); } } public void Close() { foreach (var connection in _candidateConnections) { connection.Close(); } } public async Task OpenAsync() { bool anyOk = false; var message = new StringBuilder(); for (int i = _candidateConnections.Count - 1; i >= 0; i--) { try { await _candidateConnections[i].OpenAsync(); if (!anyOk) anyOk = true; } catch (Exception ex) { Debug.WriteLine(ex); message.AppendLine(ex.Message); //_candidateConnections.RemoveAt(i); } } if (!anyOk) { throw new Exception(message.ToString()); } } public async Task ReadAsync(byte[] buffer, int offset, int count) { int result; for (int i = 0; i < _candidateConnections.Count; i++) { if (_candidateConnections[i].IsOpen) { try { result = await _candidateConnections[i].ReadAsync(buffer, offset, count); if (result != 0) { //if (i != 0) //{ // var tmp = _candidateConnections[i]; // _candidateConnections[i] = _candidateConnections[0]; // _candidateConnections[0] = tmp; //} //for (int j = _candidateConnections.Count - 1; j > 0; j--) //{ // _candidateConnections[j].Close(); // _candidateConnections.RemoveAt(j); //} return result; } } catch (Exception ex) { Debug.WriteLine(ex); ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex)); } } } return 0; } public async Task WriteAsync(byte[] buffer, int offset, int count) { for (int i = 0; i < _candidateConnections.Count; i++) { if (_candidateConnections[i].IsOpen) { try { await _candidateConnections[i].WriteAsync(buffer, offset, count); } catch (Exception ex) { Debug.WriteLine(ex); ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex)); } } } } } }