8
8
by itself.
9
9
"""
10
10
import asyncio
11
- from asyncio import Future
11
+ from asyncio import Future , Task
12
12
from collections .abc import Awaitable , Callable
13
13
from typing import Any , TypeVar
14
14
@@ -58,6 +58,12 @@ def cancel(_: OperationCanceledError) -> None:
58
58
return future
59
59
60
60
61
+ # Tasks that are scheduled on the main event loop. The main event loop keeps a
62
+ # a weak reference to the tasks, so we need to keep a strong reference to them until
63
+ # they are completed.
64
+ __running_tasks : set [Task [Any ]] = set ()
65
+
66
+
61
67
def start (computation : Awaitable [Any ], token : CancellationToken | None = None ) -> None :
62
68
"""Start computation.
63
69
@@ -69,9 +75,12 @@ def start(computation: Awaitable[Any], token: CancellationToken | None = None) -
69
75
"""
70
76
71
77
async def runner () -> Any :
72
- return await computation
78
+ result = await computation
79
+ __running_tasks .remove (task )
80
+ return result
73
81
74
82
task = asyncio .create_task (runner ())
83
+ __running_tasks .add (task )
75
84
76
85
def cb ():
77
86
task .cancel ()
@@ -89,9 +98,12 @@ def start_immediate(computation: Awaitable[Any], token: CancellationToken | None
89
98
"""
90
99
91
100
async def runner () -> Any :
92
- return await computation
101
+ result = await computation
102
+ __running_tasks .remove (task )
103
+ return result
93
104
94
105
task = asyncio .create_task (runner ())
106
+ __running_tasks .add (task )
95
107
96
108
def cb () -> None :
97
109
task .cancel ()
0 commit comments