public override async Task <string> EnqueueAsync(T data) { string id = Guid.NewGuid().ToString("N"); _logger.Trace("Queue {0} enqueue item: {1}", typeof(T).Name, id); if (!await OnEnqueuingAsync(data).AnyContext()) { return(null); } var entry = new QueueEntry <T>(id, data.Copy(), this, DateTime.UtcNow, 0); _queue.Enqueue(entry); _logger.Trace("Enqueue: Set Event"); using (await _monitor.EnterAsync()) _monitor.Pulse(); Interlocked.Increment(ref _enqueuedCount); await OnEnqueuedAsync(entry).AnyContext(); _logger.Trace("Enqueue done"); return(id); }
public void Locked_PreventsLockUntilUnlocked() { AsyncContext.Run(async() => { var monitor = new AsyncMonitor(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); Task <IDisposable> initialLockTask = null; var task1 = Task.Run(async() => { initialLockTask = monitor.EnterAsync(); using (await initialLockTask) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; var lockTask = monitor.EnterAsync(); Assert.IsFalse(lockTask.IsCompleted); task1Continue.SetResult(); await lockTask; }); }
/// <summary> /// Wait for the model to be fully updated from RepRapFirmware /// </summary> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Asynchronous task</returns> public static async Task WaitForFullUpdate(CancellationToken cancellationToken) { using (await _monitor.EnterAsync(cancellationToken)) { await _monitor.WaitAsync(cancellationToken); Program.CancelSource.Token.ThrowIfCancellationRequested(); } }
/// <summary> /// Merge a received status response into the object model /// </summary> /// <param name="module">Module that is supposed to be merged</param> /// <param name="json">JSON data</param> /// <returns>Asynchronous task</returns> public static async Task ProcessResponse(byte module, Memory <byte> json) { using (await _monitor.EnterAsync(Program.CancelSource.Token)) { _module = module; json.CopyTo(_json); _jsonLength = json.Length; _monitor.Pulse(); } }
// Background work private async Task ProcessingRpc(CancellationToken ct) { while (!ct.IsCancellationRequested) { var rpc = await netCh.DequeueAsync(ct); logger.Debug("Processing RPC"); await ProcessRpcAsync(rpc, ct); using (await netChMonitor.EnterAsync()) { netChMonitor.Pulse(); } } }
public void Pulse_ReleasesOneWaiter() { AsyncContext.Run(async() => { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = new TaskCompletionSource(); var task2Ready = new TaskCompletionSource(); Task <IDisposable> lockTask1 = null; Task waitTask1 = null; var task1 = Task.Run(async() => { lockTask1 = monitor.EnterAsync(); using (await lockTask1) { waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; Task <IDisposable> lockTask2 = null; Task waitTask2 = null; var task2 = Task.Run(async() => { lockTask2 = monitor.EnterAsync(); using (await lockTask2) { waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; Task <IDisposable> lockTask3 = monitor.EnterAsync(); using (await lockTask3) { monitor.Pulse(); } await Task.WhenAny(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.AreEqual(1, result); }); }
public async Task Unlocked_PermitsLock() { var monitor = new AsyncMonitor(); var task = monitor.EnterAsync(); await task; }
private async Task AddingTransactions(CancellationToken ct) { while (!ct.IsCancellationRequested) { var tx = await submitCh.DequeueAsync(ct); logger.Debug("Adding Transaction"); await AddTransaction(tx, ct); using (await submitChMonitor.EnterAsync()) { submitChMonitor.Pulse(); } } }
public async Task Unlocked_PermitsLock() { AsyncMonitor monitor = new AsyncMonitor(); AwaitableDisposable <IDisposable> task = monitor.EnterAsync(); await task; }
public async Task CommitBlocksCompleted() { using (await commitChMonitor.EnterAsync()) { await commitChMonitor.WaitAsync(); } }
public async Task AddingTransactionsCompleted() { using (await submitChMonitor.EnterAsync()) { await submitChMonitor.WaitAsync(); } }
/// <summary> /// Wait for the model to be fully updated from RepRapFirmware /// </summary> /// <returns>Asynchronous task</returns> public static async Task WaitForFullUpdate() { using (await _updateEvent.EnterAsync()) { await _updateEvent.WaitAsync(Program.CancelSource.Token); Program.CancelSource.Token.ThrowIfCancellationRequested(); } }
public async Task JobLoop(CancellationToken cancellationToken) { try { using (await jobLock.EnterAsync(cancellationToken)) { while (!cancellationToken.IsCancellationRequested) { while (runningJobs < maxJobs) { _ = Task.Run(() => JobFiber(cancellationToken), cancellationToken); ++runningJobs; } await jobLock.WaitAsync(cancellationToken); } } } catch (OperationCanceledException) {} }
public async Task PulseAll_ReleasesAllWaiters() { AsyncMonitor monitor = new AsyncMonitor(); int[] completed = { 0 }; TaskCompletionSource <object> task1Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); TaskCompletionSource <object> task2Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); Task waitTask1 = null; Task task1 = Task.Run(async() => { using (await monitor.EnterAsync()) { waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(null); await waitTask1; Interlocked.Increment(ref completed[0]); } }); await task1Ready.Task; Task waitTask2 = null; Task task2 = Task.Run(async() => { using (await monitor.EnterAsync()) { waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(null); await waitTask2; Interlocked.Increment(ref completed[0]); } }); await task2Ready.Task; AwaitableDisposable <IDisposable> lockTask3 = monitor.EnterAsync(); using (await lockTask3) { monitor.PulseAll(); } await Task.WhenAll(task1, task2).ConfigureAwait(false); int result = Interlocked.CompareExchange(ref completed[0], 0, 0); Assert.Equal(2, result); }
public void PulseAll_ReleasesAllWaiters() { Test.Async(async() => { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = new TaskCompletionSource(); var task2Ready = new TaskCompletionSource(); Task waitTask1 = null; var task1 = TaskShim.Run(async() => { using (await monitor.EnterAsync()) { waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; Task waitTask2 = null; var task2 = TaskShim.Run(async() => { using (await monitor.EnterAsync()) { waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; var lockTask3 = monitor.EnterAsync(); using (await lockTask3) { monitor.PulseAll(); } await TaskShim.WhenAll(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.AreEqual(2, result); }); }
public void Unlocked_PermitsLock() { Test.Async(async() => { var monitor = new AsyncMonitor(); var task = monitor.EnterAsync(); await task; }); }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception> public async ValueTask <bool> MoveNextAsync() { using (await monitor.EnterAsync()) { while (cached.Count == 0 && active) { await monitor.WaitAsync(); } if (active == false && cached.Count == 0) { return(false); } current = cached.Dequeue(); return(true); } }
public async Task PulseAll_ReleasesAllWaiters() { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); var task2Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); Task waitTask1 = null; var task1 = Task.Run(async() => { using (await monitor.EnterAsync()) { waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(null); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; Task waitTask2 = null; var task2 = Task.Run(async() => { using (await monitor.EnterAsync()) { waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(null); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; var lockTask3 = monitor.EnterAsync(); using (await lockTask3) { monitor.PulseAll(); } await Task.WhenAll(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.Equal(2, result); }
public async Task <byte[]> GetRpcResultAsync(long callUid, CancellationToken token) { IDisposable monitor = null; try { monitor = await m_monitor.EnterAsync(token).ConfigureAwait(false); if (!m_blockingRpcCalls.Add(callUid)) { return(null); } for (;;) { var pair = new ImmutablePair <uint, uint>((uint)callUid >> 16, (uint)callUid & 0xffff); byte[] str; if (!m_rpcResults.TryGetValue(pair, out str)) { if (m_terminating) { m_blockingRpcCalls.Remove(callUid); return(null); } await m_monitor.WaitAsync(token).ConfigureAwait(false); if (token.IsCancellationRequested) { m_blockingRpcCalls.Remove(callUid); return(null); } if (m_terminating) { m_blockingRpcCalls.Remove(callUid); return(null); } continue; } byte[] result = new byte[str.Length]; Array.Copy(str, result, result.Length); m_blockingRpcCalls.Remove(callUid); return(result); } } catch (OperationCanceledException) { // Operation canceled. Return null. return(null); } finally { monitor?.Dispose(); } }
private async Task CommitBlocks(CancellationToken ct) { while (!ct.IsCancellationRequested) { var block = await commitCh.DequeueAsync(ct); logger.Debug("Committing Block Index={Index}; RoundReceived={RoundReceived}; TxCount={TxCount}", block.Index(), block.RoundReceived(), block.Transactions().Length); var err = await Commit(block); if (err != null) { logger.Error("Committing Block", err); } using (await commitChMonitor.EnterAsync()) { commitChMonitor.Pulse(); } } }
public async Task Pulse_ReleasesOneWaiter() { var monitor = new AsyncMonitor(); int completed = 0; var task1Ready = new TaskCompletionSource <object>(); var task2Ready = new TaskCompletionSource <object>(); var task1 = Task.Run(async() => { using (await monitor.EnterAsync()) { var waitTask1 = monitor.WaitAsync(); task1Ready.SetResult(null); await waitTask1; Interlocked.Increment(ref completed); } }); await task1Ready.Task; var task2 = Task.Run(async() => { using (await monitor.EnterAsync()) { var waitTask2 = monitor.WaitAsync(); task2Ready.SetResult(null); await waitTask2; Interlocked.Increment(ref completed); } }); await task2Ready.Task; using (await monitor.EnterAsync()) { monitor.Pulse(); } await Task.WhenAny(task1, task2); var result = Interlocked.CompareExchange(ref completed, 0, 0); Assert.Equal(1, result); }
public async Task Locked_PreventsLockUntilUnlocked() { var monitor = new AsyncMonitor(); var task1HasLock = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); var task1Continue = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>(); var task1 = Task.Run(async() => { using (await monitor.EnterAsync()) { task1HasLock.SetResult(null); await task1Continue.Task; } }); await task1HasLock.Task; var lockTask = monitor.EnterAsync().AsTask(); Assert.False(lockTask.IsCompleted); task1Continue.SetResult(null); await lockTask; }
public async Task WillPulseMonitor() { var monitor = new AsyncMonitor(); var sw = Stopwatch.StartNew(); // Monitor will not be pulsed and should be cancelled after 100ms. using (await monitor.EnterAsync()) await Assert.ThrowsAsync <OperationCanceledException>(() => monitor.WaitAsync(TimeSpan.FromMilliseconds(100).ToCancellationToken())); sw.Stop(); Assert.InRange(sw.ElapsedMilliseconds, 75, 125); var t = Task.Run(async() => { await SystemClock.SleepAsync(25); using (await monitor.EnterAsync()) monitor.Pulse(); }); sw = Stopwatch.StartNew(); using (await monitor.EnterAsync()) await monitor.WaitAsync(TimeSpan.FromSeconds(1).ToCancellationToken()); sw.Stop(); Assert.InRange(sw.ElapsedMilliseconds, 25, 100); }
/// <summary> /// Executes this operation /// </summary> /// <param name="rows">The rows.</param> /// <param name="cancellationToken">A CancellationToken to stop execution</param> /// <returns></returns> public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default) { return(new AsyncEnumerable <Row>(yield => { var input = new GatedThreadSafeEnumerator <Row>(Operations.Count, rows, cancellationToken); AsyncMonitor monitor = new AsyncMonitor(); Task[] tasks = Operations .Select(async operation => { var clone = input.Select(r => r.Clone()); var result = operation.Execute(clone, cancellationToken); if (result == null) { await input.DisposeAsync(); return null; } var enumerator = result.GetAsyncEnumerator(cancellationToken); return Task.Run(async() => { try { while (await enumerator.MoveNextAsync()) { ; } } finally { using (await monitor.EnterAsync(cancellationToken)) { await enumerator.DisposeAsync(); monitor.Pulse(); } } }, cancellationToken); }) .Where(t => t?.Result != null) .Select(t => t.Result) .ToArray(); Task.WaitAll(tasks); return Task.CompletedTask; })); }
public void Locked_PreventsLockUntilUnlocked() { Test.Async(async() => { var monitor = new AsyncMonitor(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); var task1 = TaskShim.Run(async() => { using (await monitor.EnterAsync()) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; var lockTask = monitor.EnterAsync().AsTask(); Assert.IsFalse(lockTask.IsCompleted); task1Continue.SetResult(); await lockTask; }); }
public async Task <bool> StopAsync() { using (await stopSync.EnterAsync()) if (!end) { end = true; awaiter = new TaskCompletionSource <bool>(); bool result = await awaiter.Task; awaiter = null; return(result); } else { return(true); } }
public async Task <IPipelineStatus> AddJobs(IPipelineRunManager pipelineRunManager, IEnumerable <BuildJob> jobs, int buildNum, CancellationToken cancellationToken) { var dependentJobs = new HashSet <BuildJob>(); var jobMap = new Dictionary <BuildJob, IJobStatus>(); var runnableJobs = new List <RunnableJob>(); foreach (var job in jobs) { AddBuildJob(pipelineRunManager, job, runnableJobs, dependentJobs, jobMap); } var jobIds = new HashSet <string>(jobMap.Count); foreach (var buildJob in jobMap.Keys) { if (!jobIds.Add(buildJob.Id)) { throw new Exception("Duplicate job id."); } } runnableJobs.Reverse(); using (await monitor.EnterAsync(cancellationToken)) { foreach (var jobRun in runnableJobs) { await jobRun.Status.WriteBuildJobFile(); jobQueue.AddLast(jobRun); } monitor.PulseAll(); } return(new PipelineStatus( new ReadOnlyDictionary <string, IJobStatus>(jobMap.ToDictionary(kvp => kvp.Key.Id, kvp => kvp.Value)), buildNum, pipelineRunManager.PipelineDir )); }
public async Task <byte[]> ReadAsync(string fileName) { if (_cache.ContainsKey(fileName)) { return(_cache[fileName]); } using (await AsyncMonitor.EnterAsync(fileName)) { // double check cache since it can be populated in another thread if (_cache.ContainsKey(fileName)) { return(_cache[fileName]); } var fileData = await _fileReader.ReadAsync(fileName); RealReadCallCount++; _cache[fileName] = fileData; return(fileData); } }
/// <summary> /// MoveNext the enumerator /// </summary> /// <returns></returns> public async ValueTask <bool> MoveNextAsync() { using (await monitor.EnterAsync()) { if (Interlocked.Increment(ref callsToMoveNext) == numberOfConsumers) { callsToMoveNext = 0; moveNext = await innerEnumerator.MoveNextAsync(); current = innerEnumerator.Current; Debug("Pulsing all waiting threads"); monitor.PulseAll(); } else { await monitor.WaitAsync(); } } return(moveNext); }
public override async Task <QueueEntry <T> > DequeueAsync(CancellationToken cancellationToken = default(CancellationToken)) { #if DEBUG Logger.Trace().Message($"Queue {_queueName} dequeuing item...").Write(); #endif await EnsureMaintenanceRunningAsync().AnyContext(); await EnsureTopicSubscriptionAsync().AnyContext(); var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_queueDisposedCancellationTokenSource.Token, cancellationToken).Token; RedisValue value = await GetRedisValueAsync(linkedCancellationToken).AnyContext(); if (linkedCancellationToken.IsCancellationRequested && value.IsNullOrEmpty) { return(null); } #if DEBUG Logger.Trace().Message("Initial list value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString())).Write(); #endif while (value.IsNullOrEmpty && !linkedCancellationToken.IsCancellationRequested) { #if DEBUG Logger.Trace().Message("Waiting to dequeue item...").Write(); var sw = Stopwatch.StartNew(); #endif try { using (await _monitor.EnterAsync(cancellationToken)) await _monitor.WaitAsync(cancellationToken).AnyContext(); } catch (TaskCanceledException) { } #if DEBUG sw.Stop(); Logger.Trace().Message("Waited for dequeue: {0}", sw.Elapsed.ToString()).Write(); #endif value = await GetRedisValueAsync(linkedCancellationToken).AnyContext(); #if DEBUG Logger.Trace().Message("List value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString())).Write(); #endif } if (value.IsNullOrEmpty) { return(null); } await _cache.SetAsync(GetDequeuedTimeKey(value), DateTime.UtcNow.Ticks, GetDequeuedTimeTtl()).AnyContext(); try { var payload = await _cache.GetAsync <T>(GetPayloadKey(value)).AnyContext(); if (payload.IsNull) { Logger.Error().Message("Error getting queue payload: {0}", value).Write(); await _db.ListRemoveAsync(WorkListName, value).AnyContext(); return(null); } var enqueuedTimeTicks = await _cache.GetAsync <long>(GetEnqueuedTimeKey(value), 0).AnyContext(); var attemptsValue = await _cache.GetAsync <int>(GetAttemptsKey(value), -1).AnyContext(); var entry = new QueueEntry <T>(value, payload.Value, this, new DateTime(enqueuedTimeTicks, DateTimeKind.Utc), attemptsValue); Interlocked.Increment(ref _dequeuedCount); await OnDequeuedAsync(entry).AnyContext(); #if DEBUG Logger.Debug().Message("Dequeued item: {0}", value).Write(); #endif return(entry); } catch (Exception ex) { Logger.Error().Exception(ex).Message("Error getting queue payload: {0}", value).Write(); throw; } }