Ejemplo n.º 1
0
        private async Task <int> SubscribeMessages(QueueName requestQueueName, CancellationToken token)
        {
            IQueueingService queueingService = CreateProvider();
            int processedMessages            = 0;

            try
            {
                while (true)
                {
                    // process request messages
                    using (Claim claim = await queueingService.ClaimMessageAsync(requestQueueName, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1), token))
                    {
                        List <QueuedMessage> messagesToDelete = new List <QueuedMessage>();

                        foreach (QueuedMessage queuedMessage in claim.Messages)
                        {
                            CalculatorOperation operation = queuedMessage.Body.ToObject <CalculatorOperation>();
                            CalculatorResult    result;
                            switch (operation._command)
                            {
                            case "+":
                                result = new CalculatorResult(operation, operation._operand1 + operation._operand2);
                                break;

                            case "-":
                                result = new CalculatorResult(operation, operation._operand1 - operation._operand2);
                                break;

                            case "*":
                                result = new CalculatorResult(operation, operation._operand1 * operation._operand2);
                                break;

                            case "/":
                                result = new CalculatorResult(operation, operation._operand1 / operation._operand2);
                                break;

                            default:
                                throw new InvalidOperationException();
                            }

                            messagesToDelete.Add(queuedMessage);

                            // Assigning result to a local suppresses a warning about calling an asynchronous operation.
                            // In this case, we do not need to wait for the task to finish.
                            Task postTask = queueingService.PostMessagesAsync(operation._replyQueueName, token, new Message <CalculatorResult>(TimeSpan.FromMinutes(5), result));
                            processedMessages++;
                        }

                        if (messagesToDelete.Count > 0)
                        {
                            await queueingService.DeleteMessagesAsync(requestQueueName, messagesToDelete.Select(i => i.Id), token);
                        }

                        // start the dispose process using DisposeAsync so the CancellationToken is honored
                        Task disposeTask = claim.DisposeAsync(token);
                    }

                    if (token.IsCancellationRequested)
                    {
                        return(processedMessages);
                    }
                }
            }
            catch (AggregateException ex)
            {
                ex.Flatten().Handle(
                    e =>
                {
                    if (e is TaskCanceledException)
                    {
                        return(true);
                    }

                    WebException webException = e as WebException;
                    if (webException != null)
                    {
                        if (webException.Status == WebExceptionStatus.RequestCanceled)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });
                return(processedMessages);
            }
            catch (TaskCanceledException)
            {
                return(processedMessages);
            }
            catch (WebException ex)
            {
                if (ex.Status != WebExceptionStatus.RequestCanceled)
                {
                    throw;
                }

                return(processedMessages);
            }
        }