首页 > 解决方案 > 什么是 Python 等价于 C# 的 ContinueWith()

问题描述

这段代码的 Python 等价物是什么?

var firstTask = new Task(() => Foo());
var secondTask = firstTask.ContinueWith((fooResult) => Bar(fooResult));
firstTask.Start();

我假设它会使用 asyncio 库。我知道如何在 Python 中创建任务,但我找不到与 C# 的 ContinueWith() 执行相同操作的简单示例

标签: pythonpython-asyncio

解决方案


你可以使用Future.add_done_callback()回调注册函数来做同样的事情;呼应 lambda 函数支持将是:

import asyncio

def continue_task_with(task, callback, *, loop=None):
    """When a task completes, schedule a new task.

    The new task is created by calling the callback with the result of
    the first task.

    """
    def done_callback(fut):
        asyncio.ensure_future(callback(fut), loop=loop)
    task.add_done_callback(done_callback)

foo_task = asyncio.ensure_future(foo())
continue_task_with(foo_task, lambda result: bar(result))
asyncio.get_event_loop().run_forever()

所以这:

  • Foo()
  • 注册一个回调,以便在任务完成时调用。
  • 回调接收任务对象,并将该任务对象作为第一个参数传递给一个 lambda,该 lambda 从中创建一个Bar()协程。然后将 lambda 的结果安排为要运行的新任务。
  • 然后调度Foo()任务;当该任务完成时,Bar()回调被调用运行Bar()

演示:

>>> async def foo():
...     print('Running foo')
...     await asyncio.sleep(1)
...     print('Completing foo')
...     return 42
...
>>> async def bar(foo_task):
...     print('Running bar')
...     if not (foo_task.cancelled() or foo_task.exception()):
...         print('Foo completed successfully, it received', foo_task.result())
...     asyncio.get_event_loop().stop()
...
>>> foo_task = asyncio.ensure_future(foo())
>>> continue_task_with(foo_task, lambda result: bar(result))
>>> asyncio.get_event_loop().run_forever()
Running foo
Completing foo
Running bar
Foo completed successfully, it received 42

推荐阅读