async Task <TValue> CreateValue(IPendingValue <TValue> pendingValue) { ExceptionDispatchInfo dispatchInfo; do { try { var value = await pendingValue.CreateValue().ConfigureAwait(false); SetResult(value); return(value); } catch (Exception ex) { dispatchInfo = ExceptionDispatchInfo.Capture(ex.GetBaseException()); } }while (TryTake(out pendingValue)); SetException(dispatchInfo); dispatchInfo.Throw(); throw dispatchInfo.SourceException; }
public Task <TValue> GetValue(Func <IPendingValue <TValue> > pendingValueFactory) { Interlocked.Increment(ref _usage); lock (this) { if (HasValue) { return(_value.Task); } IPendingValue <TValue> pendingValue = pendingValueFactory(); if (_createValue == null) { _createValue = CreateValue(pendingValue); } else { (_pending ??= new Queue <IPendingValue <TValue> >(1)).Enqueue(pendingValue); } return(pendingValue.Value); } }
/// <summary> /// Creates a node value factory, with the inital pending value /// </summary> /// <param name="initialPendingValue">The value that brought the node to the cache</param> /// <param name="timeoutInMilliseconds">The timeout to wait for additional factories before faulting</param> public NodeValueFactory(IPendingValue <TValue> initialPendingValue, int timeoutInMilliseconds) { _timeout = timeoutInMilliseconds; _pendingCollection = new BlockingCollection <IPendingValue <TValue> >(); _value = TaskUtil.GetTask <TValue>(); _pendingCollection.Add(initialPendingValue); }
public void Add(IPendingValue <TValue> pendingValue) { if (_value.Task.Status != TaskStatus.WaitingForActivation) { pendingValue.SetValue(_value.Task); } else { _pendingCollection.Add(pendingValue); } }
bool TryTake(out IPendingValue <TValue> pendingValue) { lock (this) { if (_pending != null && _pending.Count > 0) { pendingValue = _pending.Dequeue(); return(true); } } pendingValue = default; return(false); }
public Task <TValue> GetValue(IPendingValue <TValue> pendingValue) { _nodeValueFactory.Add(pendingValue); return(_nodeValueFactory.Value); }
public Task <TValue> GetValue(IPendingValue <TValue> pendingValue) { return(_value); }