public static void FindAboveThreshold <TKey>( string ciphertext, IKeyedCipher <TKey> cipher, IKeySpaceSource <TKey> keySpace, ISpeculativePlaintextRanker speculativePlaintextRanker, Action <KeyFinderResult <TKey> > onImmediateResultFound, double threshold = 0.9, CancellationToken cancellationToken = default(CancellationToken) ) { if (ciphertext == null) { throw new ArgumentNullException(nameof(ciphertext)); } if (cipher == null) { throw new ArgumentNullException(nameof(cipher)); } if (keySpace == null) { throw new ArgumentNullException(nameof(keySpace)); } if (speculativePlaintextRanker == null) { throw new ArgumentNullException(nameof(speculativePlaintextRanker)); } if (threshold < 0 || threshold > 1) { throw new ArgumentOutOfRangeException(nameof(threshold)); } if (onImmediateResultFound == null) { throw new ArgumentNullException(nameof(onImmediateResultFound)); } Parallel.ForEach( keySpace.GetKeys(), new ParallelOptions { CancellationToken = cancellationToken }, key => { string speculativePlaintext = cipher.Decrypt(ciphertext, key); double rank = speculativePlaintextRanker.Classify(speculativePlaintext); if (rank >= threshold) { onImmediateResultFound(new KeyFinderResult <TKey>(key, speculativePlaintext, rank)); } } ); }