Explain the differences between asynchronous programming (asyncio) and multi-threading in Python, and when you would choose one over the other.