Um desenvolvedor de software está trabalhando em uma aplicaç...

Próximas questões
Com base no mesmo assunto
Q3057458 Programação
Um desenvolvedor de software está trabalhando em uma aplicação web que processa transações bancárias. Para melhorar o desempenho do sistema, ele decidiu implementar a funcionalidade de cálculo de transações de forma assíncrona utilizando a linguagem Python e a biblioteca asyncio. A declaração da função assíncrona a ser chamada começa por:
async def calcular():
Ao rodar o programa, o desenvolvedor recebeu o seguinte erro:
RuntimeError: asyncio.run() cannot be called from a running event loop

Considerando-se esse contexto, uma forma correta de chamar a função calcular é
Alternativas

Gabarito comentado

Confira o gabarito comentado por um dos nossos professores

Alternativa correta: A - asyncio.create_task(calcular())

Vamos explorar o contexto da questão. O desenvolvedor está utilizando **Python** e a biblioteca **asyncio** para melhorar o desempenho de uma aplicação web por meio do processamento assíncrono de transações bancárias. Uma das funcionalidades chave do asyncio é permitir que tarefas sejam criadas e gerenciadas sem bloquear o fluxo do programa. Para isso, é importante entender como iniciar e executar tarefas assíncronas corretamente.

Agora, vejamos as justificativas para cada alternativa:

Alternativa A: asyncio.create_task(calcular())
Esta é a alternativa correta. A função asyncio.create_task() cria uma nova tarefa para executar a função assíncrona calcular(). Isso permite que a tarefa seja agendada no loop de eventos atual sem tentar reiniciar ou interferir em loops de eventos já em execução.

Alternativa B: asyncio.run(calcular())
Esta alternativa está incorreta pois asyncio.run() é usado para iniciar um novo loop de eventos, mas só deve ser chamado quando não há um loop de eventos em execução. O erro RuntimeError: asyncio.run() cannot be called from a running event loop ocorre exatamente por tentar executar o run() nesse contexto.

Alternativa C: await calcular()
Embora esta chamada seja válida dentro de uma função assíncrona, ela não pode ser usada isoladamente no escopo global ou dentro de uma função síncrona. O await só pode ser utilizado quando já estamos dentro de um contexto assíncrono.

Alternativa D: calcular().run()
Esta alternativa está incorreta porque a chamada .run() não é uma forma válida de executar uma coroutine em Python. Não é parte da API do asyncio.

Alternativa E: asyncio.loop.run_to_complete(calcular())
Essa alternativa também está incorreta. A API do asyncio não possui o método run_to_complete. O método correto seria loop.run_until_complete(), mas, assim como asyncio.run(), ele deve ser chamado apenas quando não há um loop de eventos ativo.

Espero que essa explicação tenha ajudado a entender as nuances do uso do asyncio em Python. Gostou do comentário? Deixe sua avaliação aqui embaixo!

Clique para visualizar este gabarito

Visualize o gabarito desta questão clicando no botão abaixo

Comentários

Veja os comentários dos nossos alunos

O erro ocorre porque só pode ser usado fora de um loop de eventos ativo. Se o código já está rodando dentro de um loop assíncrono (por exemplo, dentro de uma aplicação web ou um Jupyter Notebook), o uso de gera esse erro.

A solução correta é usar , pois esse método agenda a execução assíncrona da função sem precisar reiniciar o loop de eventos.

Fonte: ChatGPT

Quando async é colocado antes do def de uma função, faz com que ela retorne um objeto Coroutine (tem haver com concorrência)

async def calcular():

print("Oi eu sou um objeto Coroutine")

O asyncio.run() justamente recebe um objeto Coroutine e o executa, criando um Event Loop e apenas um asyncio.run() pode exister nesse Event Loop, do contrário temos um "RuntimeError: asyncio.run() cannot be called from a running event loop".

Então o erro ocorre porque o dev está tentando executar o objeto dele com asyncio.run(calcular()) em um Event Loop já existente (então a letra B já vai embora por causar o erro).

Essas alternativas também são eliminadas, pois:

d) calcular().run() -> Você executa (run) um objeto Coroutine pelo asyncio.run(), ele não possui um método run().

e) asyncio.loop.run_to_complete(calcular()) -> asyncio não tem um atributo loop e esse atributo não tem um método run_to_complete()

Como a questão não fala das demais funções temos duas alternativas viáveis:

a) asyncio.create_task(calcular()) 

c) await calcular() 

Porém, sabemos de uma coisa: há um Event Loop em execução, pois o erro acontece.

Opção C garante que a função calcular() seja finalizada o que interrompe a concorrência mas garante sua execução antes de continuar com o que mais tiver na frente,

Opção A garante que a função calcular() entre no Event Loop vigente para execução, mas não que calcular() conseguirá ser executada por completo, porém isso não interrompe a concorrência com as demais funções e calcular() será executada com as demais.

Como o enunciado diz: "Para melhorar o desempenho do sistema, ele decidiu implementar a funcionalidade de cálculo de transações de forma assíncrona" dá a entender que a função calcular() deve ser executada de forma concorrente sem prejudicar o desempenho do programa, mesmo que corra o risco de não ser executada.

Logo, letra A.

(Isso foi tentando fazer sentido do gabarito ser a letra A kkkkkkk)

Fontes:

Deepseek,

https://www.youtube.com/watch?v=Qb9s3UiMSTA&ab_channel=TechWithTim,

https://docs.python.org/3/library/asyncio-task.html

Clique para visualizar este comentário

Visualize os comentários desta questão clicando no botão abaixo