有时需要发生一些非关键的异步操作,但我不想等待它完成.在Tornado的协程实现中,您可以通过简单地省略yield关键字来"触发并忘记"异步功能.
我一直试图弄清楚如何使用Python 3.5中发布的新async/ await语法来"解雇" .例如,简化的代码段:
async def async_foo():
print("Do some stuff asynchronously here...")
def bar():
async_foo() # fire and forget "async_foo()"
bar()
Run Code Online (Sandbox Code Playgroud)
但是会发生什么,bar()从不执行,而是我们得到运行时警告:
RuntimeWarning: coroutine 'async_foo' was never awaited
async_foo() # fire and forget "async_foo()"
Run Code Online (Sandbox Code Playgroud) 我正在尝试Task使用Python 3的相对较新的asyncio模块正确理解和实现两个并发运行的对象.
简而言之,asyncio似乎旨在Task通过事件循环处理异步进程和并发执行.它促进了await(在异步函数中应用)作为无回调方式的使用,等待和使用结果,而不会阻塞事件循环.(期货和回调仍然是一个可行的选择.)
它还提供了asyncio.Task()类,一个专门Future 用于包装协同程序的子类.优选地通过使用该asyncio.ensure_future()方法来调用.asyncio任务的预期用途是允许独立运行的任务与同一事件循环中的其他任务"同时"运行.我的理解是Tasks连接到事件循环,然后自动保持在await语句之间驱动协程.
我喜欢能够使用并发任务而不需要使用其中一个Executor类的想法,但我没有找到很多关于实现的详细说明.
这就是我目前正在做的事情:
import asyncio
print('running async test')
async def say_boo():
i = 0
while True:
await asyncio.sleep(0)
print('...boo {0}'.format(i))
i += 1
async def say_baa():
i = 0
while True:
await asyncio.sleep(0)
print('...baa {0}'.format(i))
i += 1
# wrap in Task object
# -> automatically attaches to event loop and executes
boo = asyncio.ensure_future(say_boo())
baa = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用不同的参数同时(大约或当然)运行多个函数,并在每分钟开始时重复该操作。
我设法得到了一个asyncio运行示例,在该示例中我callback使用不同的参数在特定时间运行一个函数,但我无法弄清楚如何在非常特定的时间运行它(并永远运行它)(即我想在每分钟开始时运行它,所以在 19:00:00、19:01:00 等等)。
Asynciocall_at应该能够做到这一点,但它使用的时间格式不是标准的 Python 时间格式,我无法弄清楚将该时间格式指定为下一分钟的 00 秒。
import asyncio
import time
def callback(n, loop, msg):
print(msg)
print('callback {} invoked at {}'.format(n, loop.time()))
async def main(loop):
now = loop.time()
print('clock time: {}'.format(time.time()))
print('loop time: {}'.format(now))
print('registering callbacks')
loop.call_at(now + 0.2, callback, 1, loop, 'a')
loop.call_at(now + 0.1, callback, 2, loop, 'b')
loop.call_soon(callback, 3, loop, 'c')
await asyncio.sleep(1)
event_loop = asyncio.get_event_loop()
try:
print('entering event loop')
event_loop.run_until_complete(main(event_loop))
finally:
print('closing event loop')
event_loop.close()
Run Code Online (Sandbox Code Playgroud) async def start(channel):
while True:
m = await client.send_message(channel, "Generating... ")
generator.makeFile()
with open('tmp.png', 'rb') as f:
await client.send_file(channel, f)
await client.delete_message(m)
await asyncio.sleep(2)
Run Code Online (Sandbox Code Playgroud)
我有一个discord bot,每2秒运行一次任务.我尝试使用无限循环,但是脚本崩溃了,Task was destroyed but it is still pending!我已经阅读了有关asyncio的协同程序的内容,但是我发现await它们都没有使用.await例如,通过运行协同程序可以避免此错误吗?
我编写的代码似乎可以实现我想要的功能,但我不确定这是否是一个好主意,因为它混合了线程和事件循环以在主线程外运行无限循环。这是一个最小的代码片段,它体现了我正在做的事情的想法:
import asyncio
import threading
msg = ""
async def infinite_loop():
global msg
while True:
msg += "x"
await asyncio.sleep(0.3)
def worker():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
asyncio.get_event_loop().run_until_complete(infinite_loop())
t = threading.Thread(target=worker, daemon=True)
t.start()
Run Code Online (Sandbox Code Playgroud)
主要思想是我有一个无限循环,每 0.3 秒操作一个全局变量。我希望这个无限循环在主线程之外运行,这样我仍然可以访问主线程中的共享变量。这在 jupyter 中特别有用,因为如果我run_until_complete在主线程中调用,我就无法再与 jupyter 交互。我希望主线程可用于交互式访问和修改msg. 在我的示例中,使用异步似乎没有必要,但我正在使用一个具有异步代码的库来运行服务器,因此这是必要的。我对 python 中的异步和线程很陌生,但我记得在某处读过/听到过,使用异步线程会带来麻烦......这是一个坏主意吗?我的方法是否存在潜在的并发问题?
目前,我有一个python脚本,只有在达到指定的日期/时间后才会启动,除非我重新指定日期/时间,否则永远不再运行:
import datetime, time
start_time = datetime.datetime(2017, 4, 27, 19, 0, 0)
while(True):
dtn = datetime.datetime.now()
if dtn >= start_time:
# Runs the main code once it hits the start_time
Run Code Online (Sandbox Code Playgroud)
但是我怎样才能使它只在每天的指定时间运行代码呢?
提前谢谢你,一定会upvote /接受答复
我正在尝试为 asyncio 事件循环创建一个周期性任务,如下所示,但是我收到了“RuntimeError:无法重用已经等待的协程”异常。显然, asyncio 不允许等待与此错误线程中讨论的相同的可等待函数。这就是我尝试实现它的方式:
import asyncio
class AsyncEventLoop:
def __init__(self):
self._loop = asyncio.get_event_loop()
def add_periodic_task(self, async_func, interval):
async def wrapper(_async_func, _interval):
while True:
await _async_func # This is where it goes wrong
await asyncio.sleep(_interval)
self._loop.create_task(wrapper(async_func, interval))
return
def start(self):
self._loop.run_forever()
return
Run Code Online (Sandbox Code Playgroud)
由于我的 while 循环,相同的可等待函数 (_async_func) 将在中间有一个睡眠间隔的情况下执行。我从如何使用 asyncio 定期执行函数中获得了实现周期性任务的灵感? .
从上面提到的错误线程,我推断 RuntimeError 背后的想法是为了让开发人员不会意外地等待同一个协程两次或更多次,因为协程将被标记为完成并产生 None 而不是结果。有没有办法可以不止一次等待相同的功能?
我很难理解它是如何AsyncIOScheduler工作的以及如何在主函数内安排一个函数,或者如何是正确的方法来做到这一点。
如何foo每 10 秒运行一次该函数?
假设我有这样的结构:
package/
controllers.py
main.py
Run Code Online (Sandbox Code Playgroud)
从文件中controllers.py我调用了一个函数foo,该函数如下所示:
async def foo():
print('Hello World')
Run Code Online (Sandbox Code Playgroud)
我想foo从文件运行该函数(以及许多其他函数)main.py,该文件如下:
import asyncio
from controllers import foo, bar
from apscheduler.schedulers.asyncio import AsyncIOScheduler
async def main():
# Init message
print('\nPress Ctrl-C to quit at anytime!\n' )
await asyncio.create_task(bar())
scheduler = AsyncIOScheduler()
scheduler.add_job(await asyncio.create_task(foo()), "interval", seconds=10)
scheduler.start()
if __name__ == "__main__":
while True:
try:
asyncio.run(main())
except Exception as e:
print("Exception: " + str(e))
Run Code Online (Sandbox Code Playgroud)
这样运行调度程序是否正确?或者每次main函数运行时定时器都会被重置?
我尝试了下面的代码,循环间隔有效,但该main …
我正在尝试创建一个简单的监控系统,它会定期检查事物并记录它们。这是我尝试使用的逻辑的简化示例,但我不断收到RuntimeWarning: coroutine 'foo' was never awaited错误消息。
我应该如何从自身重新安排异步方法?
test.py 中的代码:
import asyncio
from datetime import datetime
async def collect_data():
await asyncio.sleep(1)
return {"some_data": 1,}
async def foo(loop):
results = await collect_data()
# Log the results
print("{}: {}".format(datetime.now(), results))
# schedule to run again in X seconds
loop.call_later(5, foo, loop)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.create_task(foo(loop))
loop.run_forever()
loop.close()
Run Code Online (Sandbox Code Playgroud)
错误:
pi@raspberrypi [0] $ python test.py
2018-01-03 01:59:22.924871: {'some_data': 1}
/usr/lib/python3.5/asyncio/events.py:126: RuntimeWarning: coroutine 'foo' was never awaited
self._callback(*self._args)
Run Code Online (Sandbox Code Playgroud) python ×8
apscheduler ×1
asynchronous ×1
automation ×1
concurrency ×1
datetime ×1
discord.py ×1
python-2.7 ×1
python-3.4 ×1
python-3.5 ×1
python-3.x ×1
recursion ×1
task ×1
time ×1