Um desenvolvedor de software está trabalhando em uma aplicaç...
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 é
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