如何停止异步循环

How to stop asyncio cycle

我在这里提出一个我一直在努力解决的问题。 Python 3.8.8 - 使用 Anaconda - 使用 Spyder。

我想使用 Python 通过 bleak 库将我的 Arduino Nano BLE 33 连接到 PC。这个需要包含一些AsyncIO库的知识。

BUFFER_LENGHT = 13
PACKET_NUMBER = BUFFER_LENGHT*2 
address = "04:56:14:27:55:E8"
MODEL_NBR_UUID = "0000101a-0000-1000-8000-00805f9b34fb" 


def process_data(dati):
    data = np.array(struct.unpack('H'*BUFFER_LENGHT,dati))
    print('_____________DATA_____________')
    print(data)
    print('_____________END______________')
    
def shutdown():
    client.disconnect()
    print('_____________INTERRUPTED_____________')    
    
    
async def main(address,loop):
    global start_timestamp, stream_queue,client
    client = BleakClient(address)
    while await client.is_connected()==False:
        try:
            await client.connect()
        except Exception as e:
            print(e)
    
    try:
        time.sleep(1)
        start_timestamp=datetime.timestamp(datetime.now())
        while True:
            dati = await client.read_gatt_char(MODEL_NBR_UUID)
            process_data(dati)
            time.sleep(2)
    except Exception as e:
        print(e)
    else:
        await client.stop_notify(MODEL_NBR_UUID) 
        await client.disconnect()
        

try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main(address, loop))
        loop.close()
except KeyboardInterrupt:
        print("Process interrupted")
        loop.run_until_complete(shutdown())
        loop.close()
    
if __name__ == "__main__": 
    main()

所以,在导入所有库之后,我想使用 client.read_gatt_char(MODEL_NBR_UUID) 从 Arduino 读取一些数据,然后解压它。 我的问题是我无法停止 AsyncIO 循环。我希望使用 ctrl+C 停止代码,但它不起作用,我无法理解为什么。

try-catch结构有没有错误?或者(更现实)使用 asyncio 函数是否存在一些不精确性?

谁能帮帮我?将不胜感激。

好吧,毕竟这是 Spyder 的东西。我复制了你的代码,经过一些修复并删除了它工作的 BleakClient 东西,所以我决定下载 Spyder。

Spyder 显然是基于 IPython 并且具有一些来自普通 Python 时可能不熟悉的特性。我不确定您首先是如何在 Spyder 中获得 运行 该代码的,因为 run_until_complete 在 Spyder 的单元格中调用时会引发 RuntimeError

但通过一些修改,您可以 运行 Spyder 中的脚本:

import asyncio
from datetime import datetime
from asyncio.exceptions import CancelledError

BUFFER_LENGHT = 13
PACKET_NUMBER = BUFFER_LENGHT * 2
address = "04:56:14:27:55:E8"
MODEL_NBR_UUID = "0000101a-0000-1000-8000-00805f9b34fb"


def process_data(dati):
    data = dati
    print("_____________DATA_____________")
    print(data)
    print("_____________END______________")


async def shutdown():
    # client.disconnect()
    print("_____________INTERRUPTED_____________")


async def main(address):
    global start_timestamp, stream_queue, client
    # client = BleakClient(address)
    try:
        #await client.connect()
        print("connect")
    except Exception as e:
        print(e)

    try:
        start_timestamp = datetime.timestamp(datetime.now())
        while True:
            dati = "some data"
            process_data(dati)
            await asyncio.sleep(2)
    except CancelledError: #KeyboardInterrupt is raised as CancelledError
        print("cancelled")
    finally: # your else-block was unreachable code, use finally for finalizing stuff
        print("stop notify") # your clean-up code here
        print("disconnect")

async def start(): #new main entry point
    await main(address)

这应该开箱即用,供您使用。只需 运行 带有“播放”按钮的文件,现在您可以从 IPython 界面 运行 您的函数。

[2] await start()

将启动您的脚本。现在您应该可以在 运行ning 单元格内使用“停止”按钮或 ctrl+c 停止。 这远非完美,但我想它应该给你一个重新插入你的 BleakClient 逻辑的起点。