簡體   English   中英

Python相當於TaskCompletionSource的情況 <T> (。凈)?

[英]What would be a Python equivalent of TaskCompletionSource<T> (.NET)?

我正在嘗試實現以下偽代碼(部分受.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

什么是推薦的pythonic(或.NET風格但與python兼容)的方法來實現這一目標?

我試圖以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

該代碼仍然不是很Python,但是希望您能理解我的意思。

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]

假設提供者是python線程。 您可以使用join(timeout)方法,該方法等待線程競爭或超時。 join()始終返回None,因此要檢查線程是否仍在運行,您需要使用isAlive()。 這是實現taskCompletion的一種選擇

def taskCompletion(thread,timeout): 
   thread.join(timeout) 
   return isAlive()  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM