public bool ExternalCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors, Logger log) { var senderHostname = RequestExecutor.ConvertSenderObjectToHostname(sender); var cacheKey = new Key(senderHostname, certificate.GetCertHashString(), sslPolicyErrors); Task<CachedValue> task; if (_externalCertificateValidationCallbackCache.TryGetValue(cacheKey, out var existingTask) == false) { task = new Task<CachedValue>(() => CheckExternalCertificateValidation(senderHostname, certificate, chain, sslPolicyErrors, log)); existingTask = _externalCertificateValidationCallbackCache.GetOrAdd(cacheKey, task); if (existingTask == task) { task.Start(); if (_externalCertificateValidationCallbackCache.Count > 50) { foreach (var item in _externalCertificateValidationCallbackCache.Where(x => x.Value.IsCompleted).OrderBy(x => x.Value.Result.Until).Take(25)) { _externalCertificateValidationCallbackCache.TryRemove(item.Key, out _); } } } } CachedValue cachedValue; try { cachedValue = existingTask.Result; } catch { _externalCertificateValidationCallbackCache.TryRemove(cacheKey, out _); throw; } if (_server.Time.GetUtcNow() < cachedValue.Until) return cachedValue.Valid; var cachedValueNext = cachedValue.Next; if (cachedValueNext != null) return ReturnTaskValue(cachedValueNext); task = new Task<CachedValue>(() => CheckExternalCertificateValidation(senderHostname, certificate, chain, sslPolicyErrors, log)); var nextTask = Interlocked.CompareExchange(ref cachedValue.Next, task, null); if (nextTask != null) return ReturnTaskValue(nextTask); task.ContinueWith(done => { _externalCertificateValidationCallbackCache.TryUpdate(cacheKey, done, existingTask); }, TaskContinuationOptions.OnlyOnRanToCompletion); task.Start(); return cachedValue.Valid; // we are computing this, but may take some time, let's use cached value for now bool ReturnTaskValue(Task<CachedValue> task) { if (task.IsCompletedSuccessfully) return task.Result.Valid; // not done yet? return the cached value return cachedValue.Valid; } }