Run ASGI benchmarks on a real event loop
Summary
Replace the synchronous coroutine-stepping ASGIRunner in the GZip benchmarks with one that drives the app on a real asyncio event loop.
Rationale
The current runner steps the ASGI coroutine manually and asserts it never suspends. That makes it impossible to benchmark middleware that legitimately awaits — such as the worker-thread GZip offload proposed in #3410.
Landing this runner change separately keeps CodSpeed baselines comparable: the event loop adds a small fixed overhead (~0.2 ms) to every benchmark, and if it shipped together with a middleware change, that harness overhead would be misattributed to the middleware (it currently shows up in #3410 as a spurious ~50% regression on the bypass benchmarks, which that PR does not touch).
Once this merges, #3410 rebases to a pure middleware diff and its CodSpeed report reflects only real behavior changes.
Validation
benchmarks/gzip_benchmark.py --codspeed: 68 passedscripts/checkclean