Skip to content

Reset method problem #10

@kronic

Description

@kronic
#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;
			}
		}
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions