예제 #1
0
        public IEnumerable <Task <Possible <StrongFingerprint, Failure> > > EnumerateStrongFingerprints(WeakFingerprintHash weak, UrgencyHint urgencyHint, Guid activityId)
        {
            Contract.Requires(!IsClosed);

            using (var counter = m_counters.EnumerateStrongFingerprintsCounter())
            {
                using (var eventing = new EnumerateStrongFingerprintsActivity(BasicFilesystemCache.EventSource, activityId, this))
                {
                    eventing.Start(weak, urgencyHint);

                    // It's possible the cache could encounter an IO error when attempting to enumerate the fingerprints.
                    // This shouldn't be a fatal error. we just want to catch and record it, then continue on.
                    // Due to the use of yield a foreach loop can't be used here while still handling the error,
                    // so the enumation must be done manually.
                    using (var enumerator = m_cache.EnumerateStrongFingerprints(weak).GetEnumerator())
                    {
                        while (true)
                        {
                            StrongFingerprint strong = null;
                            try
                            {
                                if (!enumerator.MoveNext())
                                {
                                    break;
                                }

                                strong = enumerator.Current;
                            }
                            catch (IOException ex)
                            {
                                eventing.StopFailure(new StrongFingerprintEnumerationFailure(m_cache.CacheId, weak, ex));
                                yield break;
                            }
                            catch (UnauthorizedAccessException ex)
                            {
                                eventing.StopFailure(new StrongFingerprintEnumerationFailure(m_cache.CacheId, weak, ex));
                                yield break;
                            }

                            counter.YieldReturn();
                            yield return(Task.FromResult(new Possible <StrongFingerprint, Failure>(strong)));
                        }
                    }

                    eventing.Stop();
                }
            }
        }