You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Twisted Clock类顺序执行多阶段延迟任务并规避time.sleep

Fixing Sequential Delays with Twisted's Clock Class

It looks like your code has a few key issues that are preventing the delays from working as expected—let's break down the problems and fix them step by step.

Key Issues in Your Original Code

  1. Multiple Clock Instances: You're creating a new Clock in each method, so advancing one clock doesn't affect the others. All tasks need to share the same clock to coordinate timing.
  2. Immediate Function Execution: When you pass self.end_time() to additionalFunc, you're calling end_time immediately instead of waiting for the delay.
  3. Unchained Tasks: Your Deferreds aren't linked together, so both tasks run at the same time instead of sequentially.
  4. Class-level Start Time: start_time is a class variable, so it's set when the class is defined (not when you create an instance), which isn't what you want for per-instance timing.

Corrected Code

from twisted.internet.task import Clock
from twisted.internet.defer import Deferred, inlineCallbacks

class ControlTime:
    def __init__(self):
        # Initialize start time when the instance is created
        self.clock = Clock()
        self.start_time = self.clock.seconds()

    def end_time(self):
        # Use the Clock's time for consistent simulation
        current_end_time = self.clock.seconds()
        print(f"End time recorded: {current_end_time}")
        return current_end_time

    def additionalFunc(self, end_time_val):
        total_delay = end_time_val - self.start_time
        print(f'You have delayed for: {total_delay} s')

    @inlineCallbacks
    def run_sequential_tasks(self, first_delay=0, second_delay=0):
        # Wait for the first delay before running end_time
        yield self._wait_for_delay(first_delay)
        end_val = self.end_time()
        
        # Wait for the second delay before running the print function
        yield self._wait_for_delay(second_delay)
        self.additionalFunc(end_val)

    def _wait_for_delay(self, delay):
        # Helper to wrap callLater in a Deferred for easy chaining
        deferred = Deferred()
        self.clock.callLater(delay, deferred.callback, None)
        return deferred

# Usage example
if __name__ == "__main__":
    ctrl = ControlTime()
    # Run tasks: first delay 3s, then another 3s
    ctrl.run_sequential_tasks(first_delay=3, second_delay=3)
    
    # Advance the clock to trigger the first delay
    ctrl.clock.advance(3)
    # Advance again to trigger the second delay
    ctrl.clock.advance(3)

What Changed & Why

  1. Single Clock Instance: We initialize one Clock in the class constructor, so all scheduled tasks use the same clock. Advancing this clock will trigger all pending tasks in order.
  2. Chained Tasks with inlineCallbacks: This decorator lets us write sequential asynchronous code like synchronous code. We first wait for the initial delay, run end_time to get the end value, wait for the second delay, then pass that value to additionalFunc.
  3. Helper _wait_for_delay Method: This wraps callLater in a Deferred, making it easy to wait for delays using yield.
  4. Instance-level Start Time: start_time is now set in __init__, so each instance gets its own start time when it's created.
  5. No Immediate Function Calls: We call end_time only after the first delay, then pass its return value to additionalFunc after the second delay—no more immediate execution.

Testing with Real Time (Optional)

If you want to use real delays instead of a simulated Clock, replace self.clock with twisted.internet.reactor and remove the clock.advance calls. Your code will then use actual wall-clock time:

from twisted.internet import reactor

# Inside __init__:
self.clock = reactor

# Usage:
ctrl.run_sequential_tasks(3, 3)
reactor.run()

内容的提问来源于stack exchange,提问作者Working dollar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 19:47:50