为什么这个异步IO调用暂停执行?

2024-10-01 11:26:01 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的密码:

async def runTaskWrapped(options):
    layoutz = [[sg.Text("Running...", key="runstatus")]];
    windowz = sg.Window("New Task", layoutz);
    x = threading.Thread(target=runTask, args=(options,));
    x.start();
    startTime = time.time();
    while True:
        eventz, valuesz = windowz.read(timeout=100)
        if eventz == sg.WIN_CLOSED:
            if x.is_alive():
                continue
            break
        if x.is_alive() == False:
            x.join()
            windowz.FindElement('runstatus').Update(value='Done! Check the new log.txt for more info.');
            break;
        else:
            windowz.FindElement('runstatus').Update(value='Running... (' + str(math.floor(time.time()-startTime)) + ')')

asyncio.run(runTaskWrapped(options));

我已经尝试了所有的方法,但执行似乎仍然会在asyncio.run(runTaskWrapped(options));之后暂停

知道为什么会这样吗

编辑: 我尝试了threading.Thread,虽然它没有暂停执行,但pysimplegui(作为sg导入)没有做任何事情,也没有像同步调用时那样显示窗口

我也试过trio,但trio暂停了执行。 trio.run(runTaskWrapped, options);


Tags: runtrioiftimesgthreadrunningoptions
1条回答
网友
1楼 · 发布于 2024-10-01 11:26:01

调用asyncio.run(some_function())时,在some_function()返回之前,程序不会转到下一行。在您的情况下,runTaskWrapped在执行其一条“break”语句之前不会返回

我们一直在处理这类事情。如果调用任何函数f(),则在f()返回之前,程序不会继续。这是一个熟悉的概念

asyncio的不同之处在于它创建了自己的循环,称为事件循环,并从该循环中启动一些函数()。这允许您从某个函数()中启动其他任务,并且当某个函数()遇到“wait”语句时,这些其他任务有机会执行。这是一个强大的概念,如果你需要的话。但是,只有当您有两个或多个任务需要等待外部资源(如网络或串行通信链路)时,它才有用,并且其中一个任务可以在另一个任务等待时继续

函数runTaskWrapped不包含任何“等待”语句。所以asyncio创建了一个事件循环,将控制权交给runTaskWrapped。那是条死胡同。它或多或少是一个无限循环,不“等待”任何东西。因此,没有办法退出runTaskWrapped,此时您的程序实际上已经死了

为了使用asyncio,您必须对程序进行结构化,使其具有多个包含“wait”的任务

您正在编写GUI程序,这通常意味着它已经有了自己的事件循环。在某些情况下,可以同时运行GUI的事件循环和asyncio事件循环,但除非您有特定的需要,否则这不会给您带来任何好处

您还尝试将asyncio与多个线程一起使用,尽管这是可能的,但需要非常小心地完成。您可以像在任何其他Python程序中一样启动其他线程,但是这些其他线程的存在不会改变主线程中发生的事情。您必须专门编写代码来同步线程之间的事件

无论在其他线程中执行什么操作,asyncio.run(some_function())都不会返回,直到其参数完成

相关问题 更多 >