python - 如何像在 C# 中一样同步运行 Python 协程,直到第一次等待?

标签 python c# python-asyncio

我正在处理一些 asyncio Python 代码,我遇到了协程排序问题。我有一些使用 C# 的经验,所以我将使用它作为示例。

在 C# 中我可以写:

using System;
using System.Threading.Tasks;

public class Program
{
    async static Task<int> foo(int n, int delay)
    {
        Console.WriteLine("Foo start {0}",n);
        await Task.Delay(delay);
        Console.WriteLine("Foo end {0}",n);
        return 0;
    }

    public static void Main()
    {
        Task<int> t1 = foo(1,300);
        Task<int> t2 = foo(2,200);
        
        Task.WaitAll(new []{t2,t1});// Reverse on purpose
    }
}

结果如下,注意协程的开始与调用顺序相匹配,不是等待顺序。由于协程函数如何划分到生成器中,因此可以保证这一点。 IE。它们总是同步运行,直到第一个 await

Foo start 1
Foo start 2
Foo end 2
Foo end 1

但是当我在 Python 中做同样的事情时,我得到不同的顺序。

import asyncio
async def foo(n,delay):
    print(f"Foo start {n}")
    await asyncio.sleep(delay/1000)
    print(f"Foo end {n}")
    return 0


async def main():
    t1 = foo(1,300)
    t2 = foo(2,200)
    
    await asyncio.gather(t2,t1) # Reverse on purpose
    
asyncio.run(main())
Foo start 2
Foo start 1
Foo end 2
Foo end 1

我也知道这是为什么 - 因为 foo(1,300) 返回一个生成器,该生成器在等待/安排协程之前不会启动。

我的问题是如何在 Python 中实现类似 C# 的行为,这意味着协程会在调用时不间断地启动,直到第一次await

我试过了

t1 = asyncio.create_task(foo(1,300))
t2 = asyncio.create_task(foo(2,200))

哪个解决了这个问题,但调度顺序真的有保证吗?

最佳答案

asyncio.create_task(),顾名思义,创建一个task.Task实例。任务在 task.Task 的构造函数中安排

self._loop.call_soon(self.__step, context=self._context)

来自 BaseEventLoop.call_soon 的文档字符串:

Arrange for a callback to be called as soon as possible. This operates as a FIFO queue: callbacks are called in the order in which they are registered. Each callback will be called exactly once.

因此,只要您使用的事件循环不会覆盖此行为,我会说您可以按照您想要的方式使用 create_task。据我所知,asyncio 中的事件循环都没有。

关于python - 如何像在 C# 中一样同步运行 Python 协程,直到第一次等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70448827/

相关文章:

python - 未设置 Tensorflow 恢复权重

python - django-south:先有鸡+有初始数据

c# - 通用集合复制方法

python - 使用 python manage.py 测试应用程序的自定义 SimpleTestCase 子项的 ImportError

python - 如何防止 Numpy/SciPy 高斯模糊将图像转换为灰度?

c# - ASP.NET C# + Nhibernate HTTP 模块 (Session per request) - 限制请求类型

c# - C#-Emgu CV-FindContours层次结构数据始终为null

python-3.x - 如何在on_ready事件中使用change_presence? (不和谐.py)

python - 从python的协程对象中检索数据