public void Run() { var cancellationToken = _cancellationTokenSource.Token; Task.Factory.StartNew(async() => { while (!cancellationToken.IsCancellationRequested) { if (!_unverifiedTransactionPool.Any()) { await _asyncDelayer.Delay(DefaultTransactionPollingInterval, cancellationToken); continue; } var unverifiedTransactionHashes = _unverifiedTransactionPool.Keys; var transactionPool = _verifiedTransactionPool.Concat( _unverifiedTransactionPool.Values.Where(t => unverifiedTransactionHashes.Contains(t.Hash))) .ToArray(); foreach (var transactionHash in unverifiedTransactionHashes) { if (!_unverifiedTransactionPool.TryGetValue(transactionHash, out var transaction)) { continue; } var valid = this._transactionVerifier.Verify(transaction); if (transactionPool .Where(t => t.Hash != transactionHash) .Where(p => p != transaction) .SelectMany(p => p.Inputs) .Intersect(transaction.Inputs) .Any()) { valid = false; } if (valid) { _verifiedTransactionPool.Add(transaction); } _unverifiedTransactionPool.TryRemove(transactionHash, out _); OnTransactionProcessed?.Invoke(this, transaction); } } }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); }