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



这是我的代码:

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));后执行暂停

知道为什么会这样吗?

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

我也尝试了三重奏,但三重奏暂停了执行。trio.run(runTaskWrapped, options);

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

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

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

您的函数 runTaskWrapped 不包含任何"await"语句。 所以 asyncio 创建了一个事件循环,手动控制运行任务包装。 那是一条死胡同。 它或多或少是一个无限循环,不会"等待"任何东西。 因此,没有办法摆脱runTaskWrapped,此时你的程序实际上已经死了。

为了使用asyncio,你必须构建你的程序,以包含多个包含"await"的任务。

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

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

无论你在其他线程中做什么,asyncio.run(some_function((( 都不会返回,直到它的参数完成。

最新更新