Raven.Client.Document.AsyncHiLoKeyGenerator.NextIdAsync C# (CSharp) Method

NextIdAsync() public method

Create the next id (numeric)
public NextIdAsync ( IAsyncDatabaseCommands databaseCommands ) : Task
databaseCommands IAsyncDatabaseCommands
return Task
		public Task<long> NextIdAsync(IAsyncDatabaseCommands databaseCommands)
		{
			var myRange = Range; // thread safe copy
			long incrementedCurrent = Interlocked.Increment(ref myRange.Current);
			if (incrementedCurrent <= myRange.Max)
			{
				return CompletedTask.With(incrementedCurrent);
			}

			bool lockTaken = false;
			try
			{
				generatorLock.Enter(ref lockTaken);
				if (Range != myRange)
				{
					// Lock was contended, and the max has already been changed. Just get a new id as usual.
					generatorLock.Exit();
					return NextIdAsync(databaseCommands);
				}
				// Get a new max, and use the current value.
				return GetNextRangeAsync(databaseCommands)
					.ContinueWith(task =>
					{
						try
						{
							Range = task.Result;
						}
						finally
						{
							generatorLock.Exit();
						}

						return NextIdAsync(databaseCommands);
					}).Unwrap();
			}
			catch
			{
				// We only unlock in exceptional cases (and not in a finally clause) because non exceptional cases will either have already
				// unlocked or will have started a task that will unlock in the future.
				if (lockTaken)
					generatorLock.Exit();
				throw;
			}
		}

Usage Example

コード例 #1
0
		public void AsyncSequentialGeneration_NoClashesOrGaps()
		{
			using (GetNewServer())
			using (var store = new DocumentStore
			{
				Url = "http://localhost:8079"
			}.Initialize())
			{
				var gen = new AsyncHiLoKeyGenerator(store.AsyncDatabaseCommands, "When_async_generating_lots_of_keys_concurrently_there_are_no_clashes", 2);
				Test(() => gen.NextIdAsync().Result, 1, GeneratedIdCount);
			}
		}