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