Questão nº 33
Questão de Lógica de Programação e Estrutura de Dados · CESGRANRIO BASA 01/2024 (nº 33)
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:
```python
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 é
- A`asyncio.create_task(calcular())` (alternativa correta)
- B`asyncio.run(calcular())`
- C`await calcular()`
- D`calcular().run()`
- E`asyncio.loop.run_to_complete(calcular())`
Resposta comentada
Gabarito Alternativa A
Conceito-chave: asyncio é uma biblioteca para rodar código assíncrono em Python, e ela exige que você tenha um event loop (o "motor" que gerencia as tarefas). Quando você já está dentro de um event loop rodando (ex.: dentro de outra função async), não pode chamar asyncio.run(), que tenta criar um loop novo — isso causa o erro. Em vez disso, você deve agendar a tarefa no loop já existente com asyncio.create_task().
- (A) Correta:
asyncio.create_task(calcular())agenda a execução da funçãocalcular()no event loop atual, sem tentar criar um novo. É a forma correta quando já se está dentro de um loop rodando (como em um script comasyncio.run()chamando outra funçãoasync). - (B) Incorreta:
asyncio.run(calcular())tenta criar um novo event loop e rodar a corrotina até o fim, mas isso falha comRuntimeErrorse já houver um loop rodando — exatamente o erro do enunciado. É a pegadinha da banca: parece a forma mais comum, mas só funciona se chamada de fora de qualquer loop (ex.: noif __name__ == "__main__"). - (C) Incorreta:
await calcular()só pode ser usado dentro de uma funçãoasync, e mesmo assim ele executa a corrotina até o fim, bloqueando a execução da função atual até terminar — não é uma forma de "chamar" de um contexto síncrono, e não resolve o erro se usado fora de um loop. - (D) Incorreta:
calcular().run()não existe em Python — corrotinas não têm método.run(). Isso geraria umAttributeError. - (E) Incorreta:
asyncio.loop.run_to_complete(calcular())está errado porqueasyncio.loopnão é um objeto acessível diretamente (é um módulo), e o método correto serialoop.run_until_complete(), mas ainda assim exigiria obter o loop atual comasyncio.get_running_loop(), o que não é feito aqui.
Fonte: CESGRANRIO BASA 01/2024 Técnico Científico - Área de Formação: Tecnologia da Informação (Caderno Prova B). Reproduzida para fins de estudo.