private void ProcessPeers() { if (Interlocked.Exchange(ref isProcessPeers, 1) == 1) { return; } foreach (var peer in Peers.OrderByDescending(x => x.Value.PiecesRequiredAvailable)) { if (DateTime.UtcNow > peer.Value.LastActive.Add(peerTimeout)) { peer.Value.Disconnect(); continue; } if (!peer.Value.IsHandshakeSent || !peer.Value.IsHandshakeReceived) { continue; } if (Torrent.IsCompleted) { peer.Value.SendNotInterested(); } else { peer.Value.SendInterested(); } if (peer.Value.IsCompleted && Torrent.IsCompleted) { peer.Value.Disconnect(); continue; } peer.Value.SendKeepAlive(); // let them leech if (Torrent.IsStarted && Leechers.Count < maxLeechers) { if (peer.Value.IsInterestedReceived && peer.Value.IsChokeSent) { peer.Value.SendUnchoke(); } } // ask to leech if (!Torrent.IsCompleted && Seeders.Count <= maxSeeders) { if (!peer.Value.IsChokeReceived) { Seeders.TryAdd(peer.Key, peer.Value); } } } Interlocked.Exchange(ref isProcessPeers, 0); }