Пример #1
0
            public override void Dispose()
            {
                if (enumerator != null)
                {
                    enumerator.Dispose();
                    enumerator = null;
                    lookup     = null;
                }

                base.Dispose();
            }
Пример #2
0
                public async Task <bool> MoveNext(CancellationToken cancellationToken)
                {
                    // nothing to do
                    if (!await _outer.MoveNext(cancellationToken)
                        .ConfigureAwait(false))
                    {
                        return(false);
                    }

                    if (_lookup == null)
                    {
                        _lookup = await Internal.Lookup <TKey, TInner> .CreateForJoinAsync(_inner, _innerKeySelector, _comparer, cancellationToken)
                                  .ConfigureAwait(false);
                    }

                    var item = _outer.Current;

                    Current = _resultSelector(item, _lookup[_outerKeySelector(item)].ToAsyncEnumerable());
                    return(true);
                }
Пример #3
0
            protected override async Task <bool> MoveNextCore(CancellationToken cancellationToken)
            {
                switch (state)
                {
                case AsyncIteratorState.Allocated:
                    lookup = await Internal.Lookup <TKey, TElement> .CreateAsync(source, keySelector, elementSelector, comparer, cancellationToken).ConfigureAwait(false);

                    enumerator = lookup.GetEnumerator();
                    state      = AsyncIteratorState.Iterating;
                    goto case AsyncIteratorState.Iterating;

                case AsyncIteratorState.Iterating:
                    if (enumerator.MoveNext())
                    {
                        current = (IAsyncGrouping <TKey, TElement>)enumerator.Current;
                        return(true);
                    }

                    Dispose();
                    break;
                }

                return(false);
            }
Пример #4
0
            protected override async Task <bool> MoveNextCore(CancellationToken cancellationToken)
            {
                switch (state)
                {
                case AsyncIteratorState.Allocated:
                    outerEnumerator = outer.GetEnumerator();
                    mode            = State_Begin;
                    state           = AsyncIteratorState.Iterating;
                    goto case AsyncIteratorState.Iterating;

                case AsyncIteratorState.Iterating:
                    switch (mode)
                    {
                    case State_Begin:
                        if (await outerEnumerator.MoveNext(cancellationToken)
                            .ConfigureAwait(false))
                        {
                            lookup = await Internal.Lookup <TKey, TInner> .CreateForJoinAsync(inner, innerKeySelector, comparer, cancellationToken).ConfigureAwait(false);

                            if (lookup.Count != 0)
                            {
                                mode = State_DoLoop;
                                goto case State_DoLoop;
                            }
                        }

                        break;

                    case State_DoLoop:
                        item = outerEnumerator.Current;
                        var g = lookup.GetGrouping(outerKeySelector(item), create: false);
                        if (g != null)
                        {
                            count    = g._count;
                            elements = g._elements;
                            index    = 0;
                            mode     = State_For;
                            goto case State_For;
                        }

                        break;

                    case State_For:
                        current = resultSelector(item, elements[index]);
                        index++;
                        if (index == count)
                        {
                            mode = State_While;
                        }
                        return(true);

                    case State_While:
                        var hasNext = await outerEnumerator.MoveNext(cancellationToken).ConfigureAwait(false);

                        if (hasNext)
                        {
                            goto case State_DoLoop;
                        }


                        break;
                    }

                    Dispose();

                    break;
                }

                return(false);
            }
Пример #5
0
            protected override async ValueTask <bool> MoveNextCore()
            {
                switch (_state)
                {
                case AsyncIteratorState.Allocated:
                    _outerEnumerator = _outer.GetAsyncEnumerator(_cancellationToken);
                    _mode            = State_If;
                    _state           = AsyncIteratorState.Iterating;
                    goto case AsyncIteratorState.Iterating;

                case AsyncIteratorState.Iterating:
                    switch (_mode)
                    {
                    case State_If:
                        if (await _outerEnumerator.MoveNextAsync().ConfigureAwait(false))
                        {
                            _lookup = await Internal.Lookup <TKey, TInner> .CreateForJoinAsync(_inner, _innerKeySelector, _comparer, _cancellationToken).ConfigureAwait(false);

                            if (_lookup.Count != 0)
                            {
                                _mode = State_DoLoop;
                                goto case State_DoLoop;
                            }
                        }

                        break;

                    case State_DoLoop:
                        _item = _outerEnumerator.Current;
                        var g = _lookup.GetGrouping(_outerKeySelector(_item), create: false);
                        if (g != null)
                        {
                            _count    = g._count;
                            _elements = g._elements;
                            _index    = 0;
                            _mode     = State_For;
                            goto case State_For;
                        }

                        // advance to while
                        _mode = State_While;
                        goto case State_While;

                    case State_For:
                        _current = _resultSelector(_item, _elements[_index]);
                        _index++;
                        if (_index == _count)
                        {
                            _mode = State_While;
                        }

                        return(true);

                    case State_While:
                        var hasNext = await _outerEnumerator.MoveNextAsync().ConfigureAwait(false);

                        if (hasNext)
                        {
                            goto case State_DoLoop;
                        }

                        break;
                    }

                    await DisposeAsync().ConfigureAwait(false);

                    break;
                }

                return(false);
            }