async void WritePieceAsync (PieceMessage message, Piece piece) { long offset = (long) message.PieceIndex * Manager.Torrent.PieceLength + message.StartOffset; try { await DiskManager.WriteAsync (Manager.Torrent, offset, message.Data, message.RequestLength); if (Cancellation.IsCancellationRequested) return; } catch (Exception ex) { Manager.TrySetError (Reason.WriteFailure, ex); return; } finally { ClientEngine.BufferPool.Return (message.Data); } piece.TotalWritten++; // If we haven't received all the pieces to disk, there's no point in hash checking if (!piece.AllBlocksWritten) return; // Hashcheck the piece as we now have all the blocks. byte[] hash; try { hash = await DiskManager.GetHashAsync (Manager.Torrent, piece.Index); if (Cancellation.IsCancellationRequested) return; } catch (Exception ex) { Manager.TrySetError (Reason.ReadFailure, ex); return; } bool result = hash != null && Manager.Torrent.Pieces.IsValid (hash, piece.Index); Manager.OnPieceHashed (piece.Index, result, 1, 1); Manager.PieceManager.PendingHashCheckPieces[piece.Index] = false; if (!result) Manager.HashFails++; for (int i = 0; i < piece.Blocks.Length; i++) if (piece.Blocks[i].RequestedOff != null) peers.Add ((PeerId) piece.Blocks[i].RequestedOff); foreach (PeerId peer in peers) { peer.Peer.HashedPiece (result); if (peer.Peer.TotalHashFails == 5) ConnectionManager.CleanupSocket (Manager, peer); } peers.Clear (); // If the piece was successfully hashed, enqueue a new "have" message to be sent out if (result) Manager.finishedPieces.Enqueue (new HaveMessage (piece.Index)); }