using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace UdpClientLib { public class UdpClientManager : IDisposable { private readonly CancellationTokenSource _cancellationTokenSource; private readonly List _clients; private readonly List _clientTasks; private bool _disposed; public UdpClientManager() { _cancellationTokenSource = new CancellationTokenSource(); _clients = new List(); _clientTasks = new List(); } // UDP 클라이언트 추가 public SingleUdpClient AddClient(string name, string serverIp, int serverPort) { var client = new SingleUdpClient(name, serverIp, serverPort); _clients.Add(client); // 각 클라이언트를 별도 Task로 실행 var clientTask = Task.Run(() => client.RunAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); _clientTasks.Add(clientTask); Console.WriteLine($"클라이언트 '{name}' 추가 - Task로 실행 시작"); return client; } public SingleUdpClient GetClient(string name) => _clients.FirstOrDefault(c => c.Name == name); public IReadOnlyList GetAllClients() => _clients.AsReadOnly(); public bool RemoveClient(string name) { var client = GetClient(name); if (client != null) { client.Dispose(); _clients.Remove(client); Console.WriteLine($"클라이언트 '{name}' 제거됨"); return true; } return false; } public async Task WaitAllAsync() { await Task.WhenAll(_clientTasks); } public void PrintStatus() { Console.WriteLine($"\n클라이언트 상태 ({_clients.Count}개):"); foreach (var client in _clients) { Console.WriteLine($" - {client.Name}"); } Console.WriteLine(); } public void Dispose() { if (!_disposed) { _cancellationTokenSource.Cancel(); foreach (var client in _clients) { client.Dispose(); } try { Task.WaitAll(_clientTasks.ToArray(), 3000); // 3초 대기 } catch (AggregateException) { // 타임아웃은 무시 } _cancellationTokenSource.Dispose(); _disposed = true; Console.WriteLine("모든 UDP 클라이언트 매니저 종료"); } } } }