Lean  $LEAN_TAG$
RefreshEnumerator.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.IO;
18 using QuantConnect.Util;
19 using System.Collections;
20 using System.Collections.Generic;
21 
23 {
24  /// <summary>
25  /// Provides an implementation of <see cref="IEnumerator{T}"/> that will
26  /// always return true via MoveNext.
27  /// </summary>
28  /// <typeparam name="T"></typeparam>
29  public class RefreshEnumerator<T> : IEnumerator<T>
30  {
31  private T _current;
32  private IEnumerator<T> _enumerator;
33  private readonly Func<IEnumerator<T>> _enumeratorFactory;
34 
35  /// <summary>
36  /// Initializes a new instance of the <see cref="RefreshEnumerator{T}"/> class
37  /// </summary>
38  /// <param name="enumeratorFactory">Enumerator factory used to regenerate the underlying
39  /// enumerator when it ends</param>
40  public RefreshEnumerator(Func<IEnumerator<T>> enumeratorFactory)
41  {
42  _enumeratorFactory = enumeratorFactory;
43  }
44 
45  /// <summary>
46  /// Advances the enumerator to the next element of the collection.
47  /// </summary>
48  /// <returns>
49  /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
50  /// </returns>
51  /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
52  public bool MoveNext()
53  {
54  if (_enumerator == null)
55  {
56  _enumerator = _enumeratorFactory.Invoke();
57  }
58 
59  var moveNext = false;
60  try
61  {
62  moveNext = _enumerator.MoveNext();
63  if (moveNext)
64  {
65  _current = _enumerator.Current;
66  }
67  }
68  catch (IOException exception)
69  {
70  // we will ignore stale file handle exceptions and retry instead, enumerator will be refreshed
71  if (exception.Message == null || !exception.Message.Contains("Stale file handle", StringComparison.InvariantCultureIgnoreCase))
72  {
73  throw;
74  }
75  }
76 
77  if (!moveNext)
78  {
79  _enumerator.DisposeSafely();
80 
81  _enumerator = null;
82  _current = default(T);
83  }
84 
85  return true;
86  }
87 
88  /// <summary>
89  /// Sets the enumerator to its initial position, which is before the first element in the collection.
90  /// </summary>
91  /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
92  public void Reset()
93  {
94  if (_enumerator != null)
95  {
96  _enumerator.Reset();
97  }
98  }
99 
100  /// <summary>
101  /// Gets the element in the collection at the current position of the enumerator.
102  /// </summary>
103  /// <returns>
104  /// The element in the collection at the current position of the enumerator.
105  /// </returns>
106  public T Current
107  {
108  get { return _current; }
109  }
110 
111  /// <summary>
112  /// Gets the current element in the collection.
113  /// </summary>
114  /// <returns>
115  /// The current element in the collection.
116  /// </returns>
117  /// <filterpriority>2</filterpriority>
118  object IEnumerator.Current
119  {
120  get { return Current; }
121  }
122 
123  /// <summary>
124  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
125  /// </summary>
126  /// <filterpriority>2</filterpriority>
127  public void Dispose()
128  {
129  if (_enumerator != null)
130  {
131  _enumerator.Dispose();
132  }
133  }
134  }
135 }