[英]What would be a Python equivalent of TaskCompletionSource<T> (.NET)?
I am trying to implement the following pseudo-code (partly inspired from what would be possible with the TaskCompletionSource<T>
in .NET), where the objective is to wait for a particular event to be received to continue execution (or throw a TimeoutError
): 我正在尝试实现以下伪代码(部分受.NET中TaskCompletionSource<T>
启发),其目的是等待接收到特定事件以继续执行(或引发TimeoutError
):
from axel import Event
def _wait_for_provider_up(self, data_provider: Provider, ms_timeout: int) -> bool:
if provider.State == ProviderState.Connected: return True
if provider.State == ProviderState.Faulted: return False
taskCompletion = TaskCompletionSource<bool>()
def onStateChanged(sender, e: ProviderStateChangedEventArgs):
if e.State == ProviderState.Connected:
taskCompletion.TrySetResult(True)
elif e.State == ProviderState.Faulted:
taskCompletion.TrySetResult(False)
provider.StateChanged += onStateChanged
try:
if provider.State == ProviderState.Connected: return True
elif provider.State == ProviderState.Faulted: return False
if not taskCompletion.Task.Wait(ms_timeout) or not taskCompletion.Task.Result or provider.State != ProviderState.Connected:
return False
finally:
provider.StateChanged -= onStateChanged
return True
What would be a recommended pythonic (or .NET-ish but python-compatible) way to achieve that? 什么是推荐的pythonic(或.NET风格但与python兼容)的方法来实现这一目标?
I've tried to rewrite your code in asyncio
way but please pay attention: function _wait_for_provider_up
has been changed to coroutine
: 我试图以asyncio
方式重写您的代码,但请注意: _wait_for_provider_up
函数已更改为coroutine
:
from axel import Event
async def _wait_for_provider_up(self, data_provider: Provider, ms_timeout: int) -> bool:
if provider.State == ProviderState.Connected:
return True
if provider.State == ProviderState.Faulted:
return False
taskCompletion = asyncio.Future()
def onStateChanged(sender, e: ProviderStateChangedEventArgs):
if e.State == ProviderState.Connected:
taskCompletion.set_result(True)
elif e.State == ProviderState.Faulted:
taskCompletion.set_result(False)
provider.StateChanged += onStateChanged
try:
if provider.State == ProviderState.Connected:
return True
elif provider.State == ProviderState.Faulted:
return False
try:
result = await asyncio.wait_for(taskCompletion, timeout=ms_timeout/1000)
if not result or provider.State != ProviderState.Connected:
return False
except asyncio.TimeoutError:
return False
finally:
provider.StateChanged -= onStateChanged
return True
The code is still not very pythonic but I hope you'll get my point. 该代码仍然不是很Python,但是希望您能理解我的意思。
The python equivalent is asyncio.Future
. python等效项是asyncio.Future
。
import asyncio
source = asyncio.Future()
async def await_concat(x):
return x + await source
async def set_after_two_seconds():
print("READY")
await asyncio.sleep(2)
print("SET")
source.set_result("GO")
print(asyncio.get_event_loop().run_until_complete(asyncio.gather(
await_concat("PASS "),
set_after_two_seconds(),
)))
## prints
# READY
## (note: two second pause here)
# SET
# ['PASS GO', None]
Assuming the provider is a python thread. 假设提供者是python线程。 You can use the join(timeout) method which waits for the thread to compete or the timeout. 您可以使用join(timeout)方法,该方法等待线程竞争或超时。 join() always returns None so to check if the thread is still alive you need to use isAlive(). join()始终返回None,因此要检查线程是否仍在运行,您需要使用isAlive()。 Here is one option in implementing the taskCompletion 这是实现taskCompletion的一种选择
def taskCompletion(thread,timeout):
thread.join(timeout)
return isAlive()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.