-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Labels
Description
#region
using System;
using System.Collections.Generic;
using System.Reactive.Concurrency;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using BFF.DataVirtualizingCollection.DataVirtualizingCollection;
#endregion
namespace ConsoleApp11
{
internal static class Program
{
public static int Version = 1;
private const int NumberItem = 5;
private static readonly TimeSpan Delay = TimeSpan.FromSeconds(1);
private static readonly TimeSpan EpsilonDelay = Delay / 10;
private static TestAsyncEnumerable testAsyncEnumerable;
private static IDataVirtualizingCollection<int> dataVirtualizingCollection;
private static async Task Main()
{
testAsyncEnumerable = new TestAsyncEnumerable(NumberItem, Delay);
dataVirtualizingCollection = DataVirtualizingCollectionBuilder.Build<int>
(
10,
new TaskPoolScheduler(Task.Factory)
)
.NonPreloading()
.Hoarding()
.AsyncEnumerableBasedFetchers(PageFetcher, CountFetcher)
.AsyncIndexAccess((_, _) => -2);
await Task.Delay(EpsilonDelay);
//problem not show CountFetcher cancel
dataVirtualizingCollection.Reset();
Version++;
await Task.Delay(Delay + EpsilonDelay);
var dataVirtualizing = dataVirtualizingCollection[0];
await Task.Delay(2 * Delay + EpsilonDelay);
//problem not show PageFetcher cancel
Version++;
dataVirtualizingCollection.Reset();
//problem not run PageFetcher version 3
dataVirtualizing = dataVirtualizingCollection[0];
Console.WriteLine("End");
Console.ReadKey();
}
private static async Task<int> CountFetcher(CancellationToken cancellationToken)
{
var version = Version;
try
{
Console.WriteLine($"{nameof(CountFetcher)} begin {nameof(Version)}={version}");
await Task.Delay(Delay, cancellationToken);
Console.WriteLine($"{nameof(CountFetcher)} end {nameof(Version)}={version}");
return NumberItem;
}
catch (OperationCanceledException)
{
Console.WriteLine($"{nameof(CountFetcher)} cancel {nameof(Version)}={version}");
throw;
}
}
private static async IAsyncEnumerable<int> PageFetcher
(
int offset,
int count,
[EnumeratorCancellation] CancellationToken cancellationToken
)
{
var version = Version;
Console.WriteLine($"{nameof(PageFetcher)} begin {nameof(Version)}={version}");
await foreach (var item in testAsyncEnumerable.WithCancellation(cancellationToken))
{
yield return item;
}
Console.WriteLine($"{nameof(PageFetcher)} end {nameof(Version)}={version}");
}
}
public class TestAsyncEnumerable : IAsyncEnumerable<int>
{
private readonly int _number;
private readonly TimeSpan _delay;
public TestAsyncEnumerable(int number, TimeSpan delay)
{
_number = number;
_delay = delay;
}
public IAsyncEnumerator<int> GetAsyncEnumerator
(
CancellationToken cancellationToken
) => new TestAsyncEnumerator(_number, _delay, Program.Version, cancellationToken);
}
public class TestAsyncEnumerator : IAsyncEnumerator<int>
{
private readonly int _number;
private readonly TimeSpan _timeSpan;
private readonly int _version;
private readonly CancellationToken _cancellationToken;
public TestAsyncEnumerator(int number, TimeSpan timeSpan, int version, CancellationToken cancellationToken)
{
_number = number;
_timeSpan = timeSpan;
_version = version;
_cancellationToken = cancellationToken;
}
public int Current { get; private set; } = -1;
public ValueTask DisposeAsync()
{
Console.WriteLine($"{nameof(DisposeAsync)} {nameof(Version)}={_version}");
return default;
}
public async ValueTask<bool> MoveNextAsync()
{
try
{
Console.WriteLine($"before {nameof(MoveNextAsync)} {nameof(Current)} {Current} {nameof(Version)}={_version}");
await Task.Delay(_timeSpan, _cancellationToken);
var current = Current + 1;
if (current >= _number)
{
Console.WriteLine($"end {nameof(MoveNextAsync)} {nameof(Current)} {Current} {nameof(Version)}={_version}");
return false;
}
Current = current;
Console.WriteLine($"after {nameof(MoveNextAsync)} {nameof(Current)} {Current} {nameof(Version)}={_version}");
return true;
}
catch (OperationCanceledException)
{
Console.WriteLine($"{nameof(TestAsyncEnumerator)} is canceled {nameof(Version)}={_version}");
throw;
}
}
}
}