コード例 #1
0
        private void ProcessDownloads()
        {
            if (Interlocked.Exchange(ref _isProcessDownloads, 1) == 1)
            {
                return;
            }

            while (_incomingBlocks.TryDequeue(out var incomingBlock))
            {
                Torrent.WriteBlock(incomingBlock.Piece, incomingBlock.Block, incomingBlock.Data);
            }

            if (Torrent.IsCompleted)
            {
                Interlocked.Exchange(ref _isProcessDownloads, 0);
                return;
            }

            int[] ranked = GetRankedPieces();

            foreach (var piece in ranked)
            {
                if (Torrent.IsPieceVerified[piece])
                {
                    continue;
                }

                foreach (var peer in GetRankedSeeders())
                {
                    if (!peer.IsPieceDownloaded[piece])
                    {
                        continue;
                    }

                    // just request blocks in order
                    for (int block = 0; block < Torrent.GetBlockCount(piece); block++)
                    {
                        if (_downloadThrottle.IsThrottled)
                        {
                            continue;
                        }

                        if (Torrent.IsBlockAcquired[piece][block])
                        {
                            continue;
                        }

                        // only request one block from each peer at a time
                        if (peer.BlocksRequested > 0)
                        {
                            continue;
                        }

                        // only request from 1 peer at a time
                        if (Peers.Count(x => x.Value.IsBlockRequested[piece][block]) > 0)
                        {
                            continue;
                        }

                        int size = Torrent.GetBlockSize(piece, block);
                        peer.SendRequest(piece, block * Torrent.BlockSize, size);
                        _downloadThrottle.Add(size);
                        peer.IsBlockRequested[piece][block] = true;
                    }
                }
            }

            Interlocked.Exchange(ref _isProcessDownloads, 0);
        }