public Task Initialize() { _logger.LogConfigurationHeader("Command Handler"); RecurrentCancellableTask.StartNew(async() => await ParseCommand(Console.ReadLine()?.ToLower()), new TimeSpan(1), _inputTaskTokenSource.Token); _logger.LogConfigurationStatus("OK"); return(Task.CompletedTask); }
public Task Start() { _cancelationTokenSource = new CancellationTokenSource(); RecurrentCancellableTask.StartNew(async() => { var matches = await _client.GetMatchesAsync(_deviceToSubscribe.Id); MatchReceived?.Invoke(this, new MatchReceivedEventArgs(_deviceToSubscribe, MatchChannel.Polling, matches)); }, pollInterval: TimeSpan.FromSeconds(10), token: _cancelationTokenSource.Token, taskCreationOptions: TaskCreationOptions.LongRunning); return(Task.CompletedTask); }
public void Start() { _locator = CrossGeolocator.Current; _cancelationTokenSource = new CancellationTokenSource(); RecurrentCancellableTask.StartNew(async() => { var location = await _locator.GetPositionAsync(TimeSpan.FromSeconds(10), _cancelationTokenSource.Token).ConfigureAwait(false); LocationUpdated?.Invoke(this, new LocationUpdatedEventArgs(new Location { Longitude = location.Longitude, Altitude = location.Altitude, Latitude = location.Latitude })); }, TimeSpan.FromSeconds(10), _cancelationTokenSource.Token, TaskCreationOptions.LongRunning); }
private async Task ProcessMessages(TimeSpan?visibilityTimeout = null, CancellationToken cancellationToken = default(CancellationToken)) { var runningTasks = new ConcurrentDictionary <Task, Task>(); var semaphore = new SemaphoreSlim(_concurrentTasks, _concurrentTasks); var queuedMessages = new ConcurrentQueue <CloudMessage>(); // Define the task that fetches messages from the Azure queue RecurrentCancellableTask.StartNew( async() => { // Fetch messages from the Azure queue when the number of items in the concurrent queue falls below an "acceptable" level. if (!cancellationToken.IsCancellationRequested && queuedMessages.Count <= _concurrentTasks / 2) { using (_metrics.Measure.Timer.Time(Metrics.MessageFetchingTimer)) { IEnumerable <CloudMessage> messages = null; try { messages = await _queueManager.GetMessagesAsync(_concurrentTasks, visibilityTimeout, null, null, cancellationToken).ConfigureAwait(false); } catch (TaskCanceledException) { // The message pump is shutting down. // This exception can be safely ignored. } catch (Exception e) { _logger.InfoException("An error occured while fetching messages from the Azure queue. The error was caught and ignored.", e.GetBaseException()); } if (messages == null) { return; } if (messages.Any()) { _logger.Trace($"Fetched {messages.Count()} message(s) from the queue."); foreach (var message in messages) { queuedMessages.Enqueue(message); } } else { _logger.Trace("The queue is empty, no messages fetched."); try { // The queue is empty OnQueueEmpty?.Invoke(cancellationToken); _metrics.Measure.Counter.Increment(Metrics.QueueEmptyCounter); } catch (Exception e) { _logger.InfoException("An error occured when handling an empty queue. The error was caught and ignored.", e.GetBaseException()); } } } } }, TimeSpan.FromMilliseconds(500), cancellationToken, TaskCreationOptions.LongRunning); // Define the task that checks how many messages are queued RecurrentCancellableTask.StartNew( async() => { try { var count = await _queueManager.GetApproximateMessageCountAsync(cancellationToken).ConfigureAwait(false); count += queuedMessages.Count; _metrics.Measure.Gauge.SetValue(Metrics.QueuedMessagesGauge, count); } catch (TaskCanceledException) { // The message pump is shutting down. // This exception can be safely ignored. } catch (Exception e) { _logger.InfoException("An error occured while checking how many message are waiting in the queue. The error was caught and ignored.", e.GetBaseException()); } }, TimeSpan.FromMilliseconds(5000), cancellationToken, TaskCreationOptions.LongRunning); // Define the task pump var pumpTask = Task.Run(async() => { while (!cancellationToken.IsCancellationRequested) { await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); // Retrieved the next message from the queue and process it var runningTask = Task.Run( async() => { var messageProcessed = false; if (cancellationToken.IsCancellationRequested) { return(messageProcessed); } using (_metrics.Measure.Timer.Time(Metrics.MessageProcessingTimer)) { queuedMessages.TryDequeue(out CloudMessage message); if (message != null) { try { // Process the message OnMessage?.Invoke(message, cancellationToken); // Delete the processed message from the queue // PLEASE NOTE: we use "CancellationToken.None" to ensure a processed message is deleted from the queue even when the message pump is shutting down await _queueManager.DeleteMessageAsync(message, null, null, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { var isPoison = message.DequeueCount > _maxDequeueCount; OnError?.Invoke(message, ex, isPoison); if (isPoison) { // PLEASE NOTE: we use "CancellationToken.None" to ensure a processed message is deleted from the queue even when the message pump is shutting down await _queueManager.DeleteMessageAsync(message, null, null, CancellationToken.None).ConfigureAwait(false); } } messageProcessed = true; } } // Increment the counter if we processed a message if (messageProcessed) { _metrics.Measure.Counter.Increment(Metrics.MessagesProcessedCounter); } // Return a value indicating whether we processed a message or not return(messageProcessed); }, CancellationToken.None); // Add the task to the dictionary of tasks (allows us to keep track of the running tasks) runningTasks.TryAdd(runningTask, runningTask); // Complete the task runningTask.ContinueWith( t => { semaphore.Release(); runningTasks.TryRemove(t, out Task taskToBeRemoved); }, TaskContinuationOptions.ExecuteSynchronously) .IgnoreAwait(); } }); // Run the task pump until canceled await pumpTask.UntilCancelled().ConfigureAwait(false); // Task pump has been canceled, wait for the currently running tasks to complete await Task.WhenAll(runningTasks.Values).UntilCancelled().ConfigureAwait(false); }