Beispiel #1
0
            /// <summary>
            /// Waits until evaluation gets cancelled or a value is set
            /// </summary>
            public void Wait(ICycleDetector cycleDetector = null)
            {
                lock (this)
                {
                    if (m_result != EvaluationStatus.None)
                    {
                        return;
                    }

                    m_eventWaiters++;
                    if (m_event == null)
                    {
                        m_event = new ManualResetEvent(false);
                    }
                }

                if (cycleDetector == null)
                {
                    m_event.WaitOne();
                }
                else
                {
                    // wait for evaluation in separate thread to finish
                    m_event.WaitOne(m_startupDelay);

                    // at first, wait for a reasonable amount of time without actually starting up cycle detector
                    bool hasResult;
                    lock (this)
                    {
                        hasResult = m_result != EvaluationStatus.None;
                    }

                    if (!hasResult)
                    {
                        // after the first delay, evaluation is still neither canceled nor finished; let's make sure the cycle detector is actually started up
                        cycleDetector.EnsureStarted();
                        m_event.WaitOne(m_increasePriorityDelay);

                        // second, wait for a reasonable amount of time without tinkering with priorities
                        lock (this)
                        {
                            hasResult = m_result != EvaluationStatus.None;
                        }

                        if (!hasResult)
                        {
                            // after the second delay, evaluation is still neither canceled nor finished; let's raise priority of cycle detector while we keep waiting
                            using (cycleDetector.IncreasePriority())
                            {
                                m_event.WaitOne();

                                // third, just keep waiting until signaled, because of cancellation of because evaluation finishes
                            }
                        }
                    }
                }

                lock (this)
                {
                    Contract.Assume(m_result != EvaluationStatus.None);
                    if (--m_eventWaiters == 0)
                    {
                        m_event.Dispose();
                        m_event = null;
                    }
                }
            }