Wieso lassen so viele Programme den Benutzer so lange warten?
-
inflames2k schrieb:
Es bietet sich halt oft an, längere Operationen nicht in Asynchron auszuführen. Zum einen wie schon genannt, da es die Entwicklung vereinfacht, zum anderen aber auch, da es für den Benutzer am Ende egal ist, ob er die Anwendung nicht verwenden kann, weil sie für den Zeitraum nicht reagiert, oder weil die relevanten Steuerelemente gesperrt sind.
falsch. wenn eine anwendung nicht mehr reagiert - also die gui nicht mehr neu gezeichnet wird, z.b. wenn man das fenster verschiebt - nimmt er an, die anwendung ist abgeschmiert.
unfassbar dass im jahre 2012 offenbar immer noch leute single threaded GUIs schreiben.
-
lolhehe schrieb:
unfassbar dass im jahre 2012 offenbar immer noch leute single threaded GUIs schreiben.
Die GUI selbst ist doch eigentlich immer singlethreaded. Nur gewisse langdauernde Arbeiten werden ausgelagert.
Oder gibt es ernstzunehmende GUI toolkits, bei denen die grafische Oberfläche selbst in mehreren threads läuft?
-
lolhehe:
Ich muss sagen, das wundert mich genau auf der Ebene eben auch... und ich habe jetzt selbst ein paar asynchrone Dinge implementiert und finde das in den meisten Fällen überhaupt nicht schlimm.Einfach einen Workerthread nehmen und dem n Task zuteilen und bei Abarbeitung eben das Ergebnis die GUI schreiben. Wechselt Benutzer etwas oder tut etwas, weswegen der Task abgebrochen wird, wird der Task abgebrochen, gut ist. Und wenn man mit Ergebnissen weiterarbeiten möchte bzw. der User das können soll, blockiert man die Weiterarbeitung, sodass nicht gleichzeitig ein Task und das Arbeiten mit den Ergebnissen geschehen kann. Und soll es das, identifiziert man auch für Benutzer die Tasks eindeutig, damit er das jeweilige Ergebnis auswählen kann.
Aber irgendwie scheint das nicht so der Stand zu sein, keine Ahnung. Ich merk ja, das kann schnell kompliziert werden, aber das sehe ich mehr bei Echtzeit-Interaktion von vielen Threads, die unterschiedliche Dinge tun mit sehr vielen Abhängigkeiten, als bei ner GUI, wo man Tasks auslagert.
-
Also asynchron und multithreaded sind nicht dasselbe.
-
Hm und wie setzt man Asynchronität ohne Multithreading um?
-
Eisflamme schrieb:
Hm und wie setzt man Asynchronität ohne Multithreading um?
na eins nach dem anderen und immer schön abwechseln
-
Ja eben, aber das Verhalten wird bei Einprozessor-Maschinen ja sowieso bei Multithreading genutzt. Multithreading heißt nicht echte Parallelität. Deswegen verstehe ich nicht so recht, was die Unterscheidung zwischen Asynchronität und Multithreading soll.
Oder einfach, weil Asynchronität in diesem Fall als einfacher Spezialfall gemeint ist, den man eben doch alle Nase lang einsetzen kann?
-
Es gibt für manche Dinge asynchrone APIs, die mit Threads nix zu tun haben.
In Qt kann ich zB: mit Sockets arbeiten und die schicken mir ein Signal wenn etwas interessantes passiert (gibt was zu lesen zB.). Dafür muß ich mich nicht mit Threads rumschlagen und die Gui bleibt trotzdem aktiv. Außer natürlich man macht in dem Socket-Slot was extrem langwieriges. Das vereinfacht halt einfach die Implementierung enorm.
-
@Eisflamme
Ein Thread ist ein Thread, ganz klassisch mit eigenen Registern, eigenem Program-Counter, und das alles wird schön vom System gemacht, muss man sich nicht selbst drum kümmern.
Wenn man mehrere davon haben kann, nennt man das Multithreading.Wenn ich dagegen z.B. nen Messagepump habe und über diesen Benachrichtigungen empfange wenn diverse asynchrone IOs die ich losgetreten habe abgeschlossen wurden, dann nennt man das nicht Multithreading.
-
Okay.
-
lolhehe schrieb:
inflames2k schrieb:
Es bietet sich halt oft an, längere Operationen nicht in Asynchron auszuführen. Zum einen wie schon genannt, da es die Entwicklung vereinfacht, zum anderen aber auch, da es für den Benutzer am Ende egal ist, ob er die Anwendung nicht verwenden kann, weil sie für den Zeitraum nicht reagiert, oder weil die relevanten Steuerelemente gesperrt sind.
falsch. wenn eine anwendung nicht mehr reagiert - also die gui nicht mehr neu gezeichnet wird, z.b. wenn man das fenster verschiebt - nimmt er an, die anwendung ist abgeschmiert.
unfassbar dass im jahre 2012 offenbar immer noch leute single threaded GUIs schreiben.
Kommt drauf an, im normalfall entwickle ich auch Multi-Threaded Anwendungen. Aber eben nur soweit es Sinn macht. - Bei Anwendungen wo der Benutzer während der Aktion nichts machen können darf lagere ich das nicht extra in eine Asynchrone Operation aus.
-
und genau das verstehe ich nicht. du musst dem benutzer doch zumindest ein feedback geben, dass eine aktion läuft und er bitte warten soll, z.b. indem du eine progressbar anzeigst oder einfach nur ein "bitte warten".
wenn du das aber nicht tust und deine lange operation im GUI thread läuft, legst du damit alle repaints der GUI lahm. der benutzer kann hier nicht mehr unterscheiden zwischen "lange operation läuft noch" und "anwendung hat sich aufgehängt".
ich sage ja gar nicht, dass man jede gui anwendung total toll parallelisieren soll. aber zumindest sollte man lange operationen nicht im GUI thread ausführen sondern in einem worker thread + den user entsprechend darauf hinweisen, dass eine operation läuft, die evtl. etwas länger dauert.
das ist wahrlich keine rocket science...
-
Klar, in gewisser Hinsicht stimmte ich dir voll und ganz zu. Andererseits kann man jedoch schon in der Dokumentation auf Punkte eingehen, dass die Anwendung z.B. bei Laden von großen Datenmengen aus der DB so lang der Abruf dauert nicht bedienbar ist.
-
kommt halt auf deine kundschaft an. wenn die vollends schmerzbefreit ist, könntest du damit durchkommen.
aber mittlerweile hat selbst SAP erkannt, dass GUIs dem anwender auch gefallen sollten. UX wird mehr und mehr zu kernthema in der frontend entwicklung.
-
Eisflamme schrieb:
Hm und wie setzt man Asynchronität ohne Multithreading um?
Schon mal was von DMA gehoert? Laeuft asynchron genau wie viele andere Prozesse auf dem PC ganz ohne Multithreading, eben weils von der Hardware unterstuetzt wird.
-
Ja okay, das sind für mich halt so Spezialfälle. Wenn ein Socket das halt kann, weil der Netzwerkadapter das übernimmt, ist das für mich sowieso in gewisser Weise eine Blackbox, d.h. ob der jetzt einen extra Prozess/Thread nimmt oder die Hardware halt hineinschlüpft, ist mir persönlich natürlich egal.
Ich würde ja auch keine Sockets in extra Threads auslagern, jedoch sind die zeitaufwendigen Rechenoperationen, welche das GUI blockieren, ja eben oft nicht im Vorhinein asynchron, sonst würde ich ja auch nicht schade finden, dass bestimmte Programme (temporär) einfrieren.
-
mir kommt es eh vor, dass die meisten stalls und wartereien nicht viel mit cpu arbeit zu tun hat. ich habe lange nachdem VS.Net raus war noch VC6 benutzt, weil es immer responsiv war und die ganzen .NET versionen gerne ewig zum laden/beenden brauchen und auch manch einfacher klick (manchmal nur das hauptmenue) stallt ewig.
- seit VS2010 ist es um eonen besser geworden - Wenn man sich dann die CPU auslastung anschaut, ist die cpu idle. Manchmal ist es nur in source control plugin, ein code highlighter (intellisense) oder windows speicher verwaltung (die auf die HDD wartet) die ganz visual studio blockt.
Ich finde warten ist das toedlichste fuer meine arbeit, lieber debugge ich memory corruptions als nichts tun zu koennen. Besonders schlim sind wartezeiten von 5s-45s (hab ich mal in nem paper gelesen), da die intervalle zuwenig sind um was anderes zu tun, aber lang genug um das hirn auf "pause" zu stellen, sodass man anfaengt ueber ganz andere dinge zu denken oder doest und garnicht bemerkt, dass das worauf man wartete schon lange fertig ist.
wann immer ich solche blocker sehe, optimiere ich an jedem moeglichen ende damit es besser wird. z.B.
-meine engine mit ca 100k+ loc sammt shadern etc. hat eine rebuild zeit von <5s
dafuer hab ich unity builds eingefuehrt, so ziemlich alles (soweit es geht) was header included haben ist forward declared. viel arbeit die in templates gemacht wurde (hashes, adapter fuer scripting,...) ist jetzt ein prepass mit einer .exe (der in den build process von visual studio integriert ist, also dependencies etc. funzen). Ich habe zudem viel vom code refactored sodass ich alle zeit lang geschaetzt jeweils 10% vom code reduzieren/entfernen konnte.
-mein 3d editor startet in <1s, theoretisch konvertiert er daten von mehreren 100MB (z.b. texturen von tga ->dxt/pvrtc/atitc), dabei muss ich oft auf externe libs zugreifen die man nicht wirklich parallelisieren kann, deswegen cache ich alles und habe eine interne dependency verwaltung.
wenn z.b. jemand in include von einem script file aendert, oder von einem shader, oder das format von einer textur abaendern will, wird alles abhaengige zur laufzeit vom editor oder spiel abgeaendert/neugeladen.
ich hatte vorher keinen 3d editor (und ich hasse gui coden:( ), aber der workflow von einem cct->export->converter->gamestart ist zu schlecht um irgendwie ordentlich arbeiten zu koennen.ich glaube viele programme sind so 'schlecht', weil die entwickler schlichtweg aufgegeben haben zu versuchen zu verstehen was vor sich geht, weil sie oft die ganze verantwortung an externe libs abgegeben haben auf deren performance sie eh keinen einfluss haben.
Ich bewerte deswegen progamme/spiele anhand ihrer ladezeit. sowas wie God Of War kann man von anfang bis ende durchspielen ohne jemals einen ladebalken zu sehen, andere spiele wie z.B. http://www.youtube.com/watch?v=Lhib8lDknBM sindwenn man einfach nur spielen moechte.