2
respostas

A notificação não funcionou!

Bom dia! Eu entendi claramente explicação do vídeo, porem quando fui repetir o mesmo código, a mensagem de exceção não foi mostrada no console, mesmo utilizando o "contagem.Wait();" no bloco try, o compilador já vai direto para o "cancellationToken.ThrowIfCancellationRequested();" ,só gostaria de saber a onde errei e sanar essa duvida, agradeço desde já.

Segue o código abaixo:

//Lançando uma exceção quando a tarefa é cancelada
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Tecle algo para parar o relógio");
            CancellationTokenSource cancellationTokenSource
                = new CancellationTokenSource();

            Task contagem = new Task(() 
                => ContagemRegressiva(cancellationTokenSource.Token));
            contagem.Start();
            Console.ReadKey();

            if (contagem.IsCompleted)
            {
                Console.WriteLine("A contagem foi completada.");
            }
            else
            {
                try
                {
                    cancellationTokenSource.Cancel();
                    contagem.Wait();
                }
                catch (OperationCanceledException ex)
                {
                    Console.WriteLine("A contagem foi interrompida: {0}", ex.InnerException.Message);
                }

            }
            Console.ReadLine();
        }

        static void ContagemRegressiva(CancellationToken 
            cancellationToken)
        {
            int contador = 7;
            while (contador > 0 && 
                !cancellationToken.IsCancellationRequested)
            {
                Console.WriteLine("contador: {0}", contador);
                Thread.Sleep(500);
                contador--;
            }
            cancellationToken.ThrowIfCancellationRequested();
        }

    }
2 respostas

Olá Caio, tudo certo?

De fato não tem nada de errado com a lógica do código.

A mensagem da exceção não foi exibida porque se você colocar um breakpoint na linha cancellationToken.ThrowIfCancellationRequested(); e apertar a tecla para interromper a contagem, verá que esse método vai lançar a exceção normalmente, porém como está rodando dentro de uma thread isolada, a exceção que chega para o programa não é a OperationCanceledException e sim uma System.AggregateException, que é um tipo comum de exceção quando trabalhamos com paralelismo e multi-thread.

Desse modo, como o seu try/catch só trata a OperationCanceledException você não consegue pegar a exceção e então a mensagem não é exibida.

Basta realizar esse ajuste para tratar as exceções do tipo AggregateException, que nada mais é do que uma lista de exceções, obter o primeiro item da lista e pegar a propridade InnerException mesmo, que vai ter a mensagem de que a operação foi cancelada e o tipo dela será uma OperationCanceledException .

Espero que tenha te ajudado!

Olá bom dia, mesmo colocando o AggregateException a mensagem não e exibida no console, já ate tentei botar algo mais genérico como o Exception, mas o código ignora o catch e já vai para a linha cancellationToken.ThrowIfCancellationRequested();

 try
                {
                    cancellationTokenSource.Cancel();
                    contagem.Wait();
                }
                catch (AggregateException ex)
                {
                    Console.WriteLine("A contagem foi interrompida: {0}", ex.InnerException.Message);
                }

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software