示例#1
0
        private CalculationProcessInfo CreateCalculationProcessInfo(TParameters parameters)
        {
            CalculationProcessInfo calculationProcessInfo = new CalculationProcessInfo();

            processingCalculations.Add(parameters, calculationProcessInfo);
            return(calculationProcessInfo);
        }
示例#2
0
        private bool TryAcquireCalculationWait(
            TParameters parameters,
            out CalculationProcessInfo calculationProcessInfo)
        {
            bool result;

            try
            {
            }
            // Finally block will not be interrupted by thread aborting
            finally
            {
                result = processingCalculations.TryGetValue(parameters, out calculationProcessInfo);

                if (result)
                {
                    checked
                    {
                        calculationProcessInfo.WaitCount++;
                    }
                }
            }

            return(result);
        }
示例#3
0
        private void ReleaseCalculationWait(
            TParameters parameters,
            CalculationProcessInfo calculationProcessInfo)
        {
            calculationProcessInfo.WaitCount--;

            if (calculationProcessInfo.Done && (calculationProcessInfo.WaitCount == 0))
            {
                processingCalculations.Remove(parameters);
                calculationProcessInfo.Dispose();
            }
        }
示例#4
0
        private void CompleteCalculationProcessInfo(
            TParameters parameters,
            CalculationProcessInfo calculationProcessInfo)
        {
            calculationProcessInfo.Done = true;

            if (calculationProcessInfo.WaitCount > 0)
            {
                calculationProcessInfo.Event.Set();
            }
            else
            {
                processingCalculations.Remove(parameters);
                calculationProcessInfo.Dispose();
            }
        }
示例#5
0
        /// <summary>
        /// Returns cached result, or calculates a new one, or waits until the calculation is complete.
        /// Thread-safe.
        /// </summary>
        /// <param name="parameters">Calculation parameters</param>
        /// <returns>Calculation result</returns>
        public TResult GetResult(TParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            TResult result;

            while (true)
            {
                CalculationProcessInfo calculationProcessInfo = null;
                bool shouldWait = false;

                try
                {
                    lock (syncRoot)
                    {
                        if (cachedResults.TryGetValue(parameters, out result))
                        {
                            return(result);
                        }

                        shouldWait = TryAcquireCalculationWait(parameters, out calculationProcessInfo);

                        if (!shouldWait)
                        {
                            calculationProcessInfo = CreateCalculationProcessInfo(parameters);
                        }
                    }

                    if (shouldWait)
                    {
                        calculationProcessInfo.Event.WaitOne();
                    }
                    else
                    {
                        result = calculation(parameters);

                        lock (syncRoot)
                            cachedResults.Add(parameters, result);

                        return(result);
                    }
                }
                finally
                {
                    lock (syncRoot)
                    {
                        if (shouldWait)
                        {
                            ReleaseCalculationWait(parameters, calculationProcessInfo);
                        }
                        else if (calculationProcessInfo != null)
                        {
                            CompleteCalculationProcessInfo(parameters, calculationProcessInfo);
                        }
                    }
                }
            }
        }