Folgendes: Ich habe zwei Events, die nicht anderes machen, als nen BEEP!
Aber dieser Beep blockiert alles! Also habe ich mir gedacht, schmeiße ich das in einen anderen Thread!
Wie bringe ich ihm nun bei, dass diese Events in nem anderen Thread sind?
Geht das überhaupt?
Hallo Quallo,
es geht andersrum. Als Behandlung der Events startest du einen Thread, der dann das Beep durchführt.
herbivore
Also anders klappt das nicht?
Das ich einen Thread mache, da ne Klasse instanziere, die solche Arrays behandelt?
Hallo Quallo,
die Events werden immer in dem Thread ausgeführt, der das Event auslöst. Bei Events von Fenstern ist das der Thread, in dem das Fenster erstellt wurde. Das lässt sich nicht ändern.
Natürlich gibt es andere Arten die Kontrolle an einen anderen Thread zu übergeben, als ihn zu starten, aber der Code, der die Kontrolle übergibt, muss in die Ereignisbehandlung oder zumindest von ihr aufgerufen werden.
herbivore
Wenn das selbst programmierte Ereignisse sind, kann man die OnEvent-Methode so programmieren, dass das Ereignis asynchron ausgelöst wird.
Habe ich zwar noch nie gemacht, aber so ungefähr müsste es funktionieren:
// EventA asynchron auslösen.
protected void OnEventA() {
if(EventA != null) {
AsyncCallback callback = new AsyncCallback(HandleEventACallback);
EventA.BeginInvoke(this, EventArgs.Empty, callback, EventA);
}
}
// Asynchronen Vorgang ordentlich abschliessen.
private void HandleEventACallback(IAsyncResult ar) {
// Verwendeten Thread beenden/in den ThreadPool freigeben.
EventHandler eventA = (EventHandler)ar.AsyncState;
eventA.EndInvoke(ar);
}
public event EventHandler EventA;
Gruss
Pulpapex
Hat mal jemand EndInvoke() weggelassen? Eigentlich setzt das doch nur das Result-Objekt. Das Rückstellen des Threads in den Pool passiert ja innerhalb der AsyncCallback-Klasse, die den Thread ja auch startet, oder?
Um nochmal auf die beiden Lösungen einzugehen: AsyncCallback ist über den ThreadPool implementiert. Der ist auf 25 (?) Threads beschränkt. Wenn du also mehr als 25 dieser Events gleichzeitig behandeln musst, dass blockiert das Starten solange, bis ein Thread freigeworden ist.
In diesem Fall kann es sinnvoll sein doch den Thread per Hand zu starten, denn normale Threads kennen diese Beschränkung nicht. Darüberhinaus ist das Starten eines Threads aus dem Threadpool wohl langsamer als einen einzelnen Thread zu starten.
Und noch eine - für dich relevantere - Überlegung: Wenn du das Beep asynchron machts, dann kann der User auch zweimal das Beep gleichzeitig auslösen, es sein du blockierst explizit. Was passiert wenn du zwei Beeps gleichzeitig startest? Würde ich mal testen. Vermutlich problemlos, aber trotzdem....
Ich glaube Threads aus dem ThreadPool sind schneller. Und zwar werden in diesem doch Betriebssystem-Threads zur Wiederverwendung vorgehalten. Ich dachte der ThreadPool dient gerade zur Ressourcen- und Geschwindigkeitsoptimierung.
AsyncCallback ist keine Klasse, sondern nur ein Delegat, die Callback-Methode, die aufgerufen wird, wenn der Thread beendet wird. In der Doku steht explizit, dass EndInvoke aufgerufen werden muss, um Ressourcen wieder freizugeben. (.. hab aber keine Lust, das jetzt noch rauszusuchen .. geht ab nach hause 😉 )
Gruss
Pulpapex
Ich entsinne, in der c't einen Artikel zum Thema gelesen zu haben. Da kam wohl überraschend raus, dass die LATENZ der Threads aus dem Thread-Pool höher ist. Wenn man die Thread-Erzeugung mit einrechnet sicher nicht, sonst macht die Pool-Idee ja keinen Sinn.
Wenn ich natürlich möglichst schnell auf ein Ereignis reagieren möchte, dann könnte ich den Thread vorher erzeugen und dann bei Eintreten loslaufen lassen. Beim Threadpool muss dann erstmal geguckt werden, welcher Thread denn gerade frei ist...usw. usw.
Das würde heissen, der Threadpool erlaubt höhere Last ist aber weniger reaktionsschnell.
Ich kram das Teil mal raus, kann mich selbst nicht mehr erinnern. Vielleicht war auch der Test blödsinnig.
Statt BEEP könntest Du ja auch ding.wav per MCI tönen lassen ... der blockt nicht
Hier findest Du den Code.
Mp3 Stream abspielen
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Kann mich nicht entsinnen, dass bei ding.wav frequenz und tonlänge frei wählbar ist! g
Grüße Christoph
Lach ok ich dachte Du brauchst einfach einen Beep...
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...