异步请求处理中coroutine未await的RuntimeWarning问题咨询
Hey there! Let's tackle your two questions clearly, and also fix a couple of issues in your code that might be tripping you up.
RuntimeWarning: coroutine was never awaited? Technically, you can suppress the warning (using warnings.filterwarnings("ignore", category=RuntimeWarning)), but I'd strongly advise against it. Here's why:
- The warning is Python's way of telling you that you've created a coroutine object but never gave the event loop a chance to run it. In your case, when you call
RequestHandler.AsyncSend(...)directly, you're just creating a coroutine that sits idle—it doesn't actually execute the POST request at all. - Ignoring warnings can mask other, more serious issues down the line. Plus, unawaited coroutines can leave resources hanging (like open network connections) or cause unexpected behavior if your program exits before they're handled.
If you truly don't care about the result and just want the request to fire off in the background without blocking your main code, you need to properly schedule the coroutine with the event loop instead of just ignoring the warning.
loop.create_task() + loop.run_until_complete() correct? Nope, that advice is misleading for your use case. Let's break it down:
loop.run_until_complete(coro)will block your main thread until the coroutine finishes executing. That's the opposite of what you want if you don't care about waiting for the result.loop.create_task()adds a coroutine to the event loop's task queue, but the event loop has to be running for it to process the task. If you don't start the event loop (or if you're running in a synchronous context), the task will never run—and you'll still get that warning.
First, let's fix a critical issue: your SendPostRequest is a synchronous function (it uses blocking urllib.request calls). If you call this directly in an async function, it will block the entire event loop. Instead, you should run it in a thread pool using asyncio.run_in_executor().
Here's an updated version of your class:
import asyncio import urllib.request import json from concurrent.futures import ThreadPoolExecutor class RequestHandler: # Make this a static method since it doesn't use self @staticmethod def _send_post_request(url=None, json_data={}): # Encode JSON data = json.dumps(json_data).encode('utf8') # Config Request Header req = urllib.request.Request(url) req.add_header('Content-Type', 'application/json') # Send request and wait the response response = urllib.request.urlopen(req, data=data) return response @staticmethod async def async_send(method="post", url=None, json_data=None): if method == "post": loop = asyncio.get_event_loop() # Use a thread pool to run the blocking sync function with ThreadPoolExecutor() as executor: await loop.run_in_executor(executor, RequestHandler._send_post_request, url, json_data)
Now, if you want to fire this off without waiting:
- If your program is already running an async event loop (e.g., in an async app), just schedule the task with
asyncio.create_task():from RequestHandler import RequestHandler import asyncio async def main(): # Schedule the task to run in the background asyncio.create_task(RequestHandler.async_send(url="xxxxxx", json_data={'key':'value'})) # Do other work here without waiting asyncio.run(main()) - If you're in a synchronous script and want to run it in the background without blocking, you can start a background event loop thread:
from RequestHandler import RequestHandler import asyncio import threading def start_background_loop(loop): asyncio.set_event_loop(loop) loop.run_forever() # Create a background event loop background_loop = asyncio.new_event_loop() bg_thread = threading.Thread(target=start_background_loop, args=(background_loop,), daemon=True) bg_thread.start() # Submit the task to the background loop asyncio.run_coroutine_threadsafe(RequestHandler.async_send(url="xxxxxx", json_data={'key':'value'}), background_loop)
This way, the request runs in the background, you won't get the RuntimeWarning, and you don't have to wait for it to finish.
内容的提问来源于stack exchange,提问作者Question-er XDD

