Skip to content

Reset method problem #10

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;
			}
		}
	}
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions