簡體   English   中英

Python-計划庫-需要忙循環

[英]Python - Schedule library - Needs to get busy loop

因此,我一直在研究進度,最后使它生效。 我太激動了,沒想到還有另一個問題哈哈。 但是現在的問題是,只要主體完成,它就不會結束,我也找不到真正的解決方案。 我知道問題出在Time.sleep(1)行上,因為每當我使用KeyboardInterrput時,都會出現一個錯誤消息,說Time.sleep(1)是“問題”,而我找不到真正的解決方案來結束它。

我正在使用來自github的時間表: https : //github.com/dbader/schedule

while True:
    UserInput = input('To run Schedule task - Press y\nTo run directly - Press n\n')

    if(UserInput == 'y' or UserInput == 'Y'):
        print(Fore.RESET + space)
        TimeUser = input('What time to start script? Format - HH:MM\n')

        schedule.every().day.at(TimeUser).do(main)
        wipe()
        print('Schedule starts at: ''' + TimeUser + ' - Waiting for time...')
        idle = int(round(schedule.idle_seconds()))



        while True:
            schedule.run_pending()
            time.sleep(1)
            idle = int(round(schedule.idle_seconds()))
            if(idle < 6.0) and (idle >= 0.0):
                print('Starting in: ' + str(idle))

    elif(UserInput == 'n' or UserInput == 'N'):
        main()


    print("Wrong input - Try again")

我確實從非常友善的人那里得到了一個建議:日程表庫需要繁忙的循環。 真正的問題是,OP如何在不阻塞的情況下運行繁忙的循環,而該庫文檔中的答案是:在另一個線程中運行它。 如果他休息,預定的任務將無法完成

https://schedule.readthedocs.io/en/stable/faq.html#how-to-continuously-run-the-scheduler-without-blocking-the-main-thread

而且我仍然不理解不阻止main怎么辦。 也許有人有什么主意嗎?

在該示例中,它是該模塊的標准Schedule對象,但是通過一個額外的方法進行了擴展,您只需調用一次即可在單獨的線程中運行它。 我建議嘗試一下-最快的方法可能是創建自己的對象,該對象將Scheduler子類化,並在子類上實現run_continuously()方法。 然后,您可以一次在調度程序上調用該方法,然后在主線程中執行您想做的其他任何事情,而不必定期調用run_pending()

按下Ctrl + C時出現的錯誤不是問題-只是抱怨手動終止sleep中斷。 如果要基於某些條件自動退出,則可以基於循環中的某些邏輯來執行此操作

例如while not terminate:終止是您已設置的變量,可能是全局變量,可以通過計划任務進行更改。

這種基於計划的模型的許多實用程序用於后台任務,這些任務會重復運行較長時間。 假設您想執行更多代碼,或者您有一些代碼需要運行一次,並且可能可以在進入while循環之前運行,或者您想重復運行它,也可以將其添加到計划中。

一些例子

import schedule
import threading
import time

# this is a class which uses inheritance to act as a normal Scheduler,
# but also can run_continuously() in another thread
class ContinuousScheduler(schedule.Scheduler):
      def run_continuously(self, interval=1):
            """Continuously run, while executing pending jobs at each elapsed
            time interval.
            @return cease_continuous_run: threading.Event which can be set to
            cease continuous run.
            Please note that it is *intended behavior that run_continuously()
            does not run missed jobs*. For example, if you've registered a job
            that should run every minute and you set a continuous run interval
            of one hour then your job won't be run 60 times at each interval but
            only once.
            """
            cease_continuous_run = threading.Event()

            class ScheduleThread(threading.Thread):
                @classmethod
                def run(cls):
                    # I've extended this a bit by adding self.jobs is None
                    # now it will stop running if there are no jobs stored on this schedule
                    while not cease_continuous_run.is_set() and self.jobs:
                        # for debugging
                        # print("ccr_flag: {0}, no. of jobs: {1}".format(cease_continuous_run.is_set(), len(self.jobs)))
                        self.run_pending()
                        time.sleep(interval)

            continuous_thread = ScheduleThread()
            continuous_thread.start()
            return cease_continuous_run

# example using this custom scheduler that can be run in a separate thread
your_schedule = ContinuousScheduler()
your_schedule.every().day.do(print)

# it returns a threading.Event when you start it.
halt_schedule_flag = your_schedule.run_continuously()

# you can now do whatever else you like here while that runs

# if your main script doesn't stop the background thread, it will keep running
# and the main script will have to wait forever for it

# if you want to stop it running, just set the flag using set()
halt_schedule_flag.set()

# I've added another way you can stop the schedule to the class above
# if all the jobs are gone it stops, and you can remove all jobs with clear()
your_schedule.clear()

# the third way to empty the schedule is by using Single Run Jobs only
# single run jobs return schedule.CancelJob

def job_that_executes_once():
    # Do some work ...
    print("I'm only going to run once!")
    return schedule.CancelJob

# using a different schedule for this example to avoid some threading issues
another_schedule = ContinuousScheduler()
another_schedule.every(5).seconds.do(job_that_executes_once)
halt_schedule_flag = another_schedule.run_continuously()

我會留意您是否真的需要為此使用線程-如果您只是在找工作一次之后尋找程序退出,那么您要做的就是:

while schedule.jobs:
    schedule.run_pending()
    time.sleep(1)

並確保您的工作返回CancelJob 希望該示例對repl.it進行了測試,並且可以在Python 3上正常運行。

暫無
暫無

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

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