private IEnumerator <T> GetEnumerator_() { var i = 0; try { while (true) { if (_disposed) { throw new ObjectDisposedException(""); } var hasValue = default(bool); var current = default(T) !; lock (_gate) { if (i >= _buffer.Count) { if (!_stopped) { try { hasValue = _source.MoveNext(); if (hasValue) { current = _source.Current; } } catch (Exception ex) { _stopped = true; _error = ex; _source.Dispose(); } } if (_stopped) { if (_error != null) { throw _error; } else { break; } } if (hasValue) { _buffer.Add(current); } } else { hasValue = true; } } if (hasValue) { yield return(_buffer[i]); } else { break; } i++; } } finally { if (_buffer != null) { _buffer.Done(i + 1); } } }