2011-12-16 20 views
0

私は単純なPyGTKアプリケーションを持っています。私はいくつかのデータを取得し、GUIをリフレッシュするために、複数の定期的なタスクを実行する必要があるので、私はこのようなスレッドを拡張:オンデマンドトリガー付きの定期的なPythonスレッド

class MyThread(threading.Thread):   
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.setDaemon(True) 
     self.event = threading.Event() 
     self.event.set() 

    def run(self): 
     while self.event.is_set(): 
      timer = threading.Timer(60, self._run) 
      timer.start() 
      timer.join() 

    def cancel(self): 
     self.event.clear() 

    def _run(self): 
     gtk.threads_enter() 
     # do what need to be done, fetch data, update GUI 
     gtk.threads_leave() 

私はいくつかのリストに保存し、アプリケーションのブートストラップにスレッドを開始し、終了前にそれらをキャンセルします。これは完璧に機能します。

しかし、現在実行中でない場合は、スレッドの1つを即時に実行させ、実行するまでの時間を待機させないようにするリフレッシュボタンを追加します。

bool varをMyThreadに追加して、スレッドが実行中であるかどうかを示し、実行時にリセットされたMyThread._run()を呼び出すだけです私のアプリが応答しなくなり、実行を決して完了しない_runタスク。

なぜこのようなことが起こるのかわかりません。この問題を解決する最良の方法は何ですか?バックグラウンドでリフレッシュを実行すると、GUIをブロックしないようにすることもできます。

実行を呼び出して秒数を1にするとタイマーが早くトリガできるようになるのでしょうか?

答えて

2

Timerを使用する代わりに、別のEventオブジェクトをタイムアウトと組み合わせて使用​​してください。ボタンコールバックからそのイベントを設定することができます。次のコードはこれを示しています(キャンセルコードを取り除いて、短くしています)。

import threading 

class MyThread(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 
     self.sleep_event = threading.Event() 
     self.damon = True 

    def run(self): 
     while True: 
      self.sleep_event.clear() 
      self.sleep_event.wait(60) 
      threading.Thread(target=self._run).start() 

    def _run(self): 
     print "run" 

my_thread = MyThread() 
my_thread.start() 

while True: 
    raw_input("Hit ENTER to force execution\n") 
    my_thread.sleep_event.set() 

デフォルトでは、「実行」は60秒ごとに印刷されます。 ENTERを押すと、すぐに印刷され、60秒後にもう一度印刷されます。

+0

ありがとう!それはまさに私が探していたものです。 – umpirsky

関連する問題