Hallo
Ich hab hier mehrere Fälle, wo es trotz Threading zu Spinnern kommt.
Ist das tatsächlich so, dass auch bei Threading Spinner kommen oder mach ich da was falsch ?
Hier mal ein Beispiel für eine Klasse zum Ausführen von Consolen-Befehlen (im konkreten Fall für "apt-get update").
Trotz Threading kommen hier kurz Spinner, wenn der Befehl mal etwas länger ausgeführt wird.
Die Ausführung dauert meist so um die 5 Sekunden (mal ohne und mal mit kurzem Spinner).
Ok, ich hab hier inzwischen eConsoleAppContainer in Verwendung, wo es Dank der callback-Funktion keine Spinner gibt.
Mich interessiert das aber trotzdem mal ganz allgemein, wie man normale länger andauernde Funktionen in einen Thread auslagert, um Spinner zu vermeiden.
class Command(object):
def __init__(self, cmd):
self.cmd = cmd
self.process = None
def run(self, timeout):
def target():
print '=====[UpdateCheck] command-Thread started'
self.process = subprocess.Popen(self.cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(self.out,self.err) = self.process.communicate()
print '=====[UpdateCheck] command-Thread finished'
thread = threading.Thread(target=target)
thread.start()
self.timeout=False
thread.join(float(timeout))
if thread.is_alive():
print '=====[UpdateCheck] Terminating command-process by timeout:', self.cmd
self.process.terminate()
self.timeout=True
self.process = None
thread = None
return
Alles anzeigen
So sieht dann der Aufruf der Class aus:
command = Command("apt-get update")
command.run(timeout=20)
if command.timeout:
self["status"].setText("update timeout")
return
elif command.process.returncode == 0:
self["status"].setText("update complete" + str(command.out))
else:
self["status"].setText("update error: " + str(command.process.returncode) + " - " + str(command.err))
return
...
Alles anzeigen
Das gleiche Problem hab ich mit dem pzymail.
Da dauert das imap-Login auch manchmal etwas länger, was dann auch zu unschönen Spinnern führt.
Hab mir die Login-Funktion schon als SimpleThread-Aufruf umgebaut. Aber ganz ohne Spinner klappt das da auch nicht.
Aufruf:
def _imap_connect_thread(self, readonly = True):
import Queue
from Plugins.SystemPlugins.Toolkit.SimpleThread import SimpleThread
out_queue1 = Queue.Queue()
t = SimpleThread(self._imap_connect(out_queue1, readonly=readonly))
t.start()
t.join()
return out_queue1.get()
Login-Funktion (stark verkürzt dargestellt):
def _imap_connect(self, out_queue1, readonly=True):
imapObject = IMAP4_SSL(host=popserverhost, port=popserverport)
(retcode, capabilities) = imapObject.login(popuser,poppass)
imapObject.select(mailbox='INBOX', readonly=readonly)
self.imapObject = imapObject
out_queue1.put(imapObject)
return
Auch hier dauert das .login bzw. das .select mal ein paar Sekunden, was dann mit den unschönen Spinnern begleitet wird.
Was muss man tun, um die Spinner zu vermeiden?
Das ganze läuft ja bei beiden Fällen im Hintergrund, so dass es nicht stört, wenn die Abfrage etwas länger dauert.
Was nur stört, sind die Spinner, weil man jedesmal denkt, die Box hat sich aufgehängt