Laden...

Events in einem thread abfackeln!

Erstellt von Quallo vor 18 Jahren Letzter Beitrag vor 18 Jahren 3.346 Views
Q
Quallo Themenstarter:in
992 Beiträge seit 2005
vor 18 Jahren
Events in einem thread abfackeln!

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?

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Quallo,

es geht andersrum. Als Behandlung der Events startest du einen Thread, der dann das Beep durchführt.

herbivore

Q
Quallo Themenstarter:in
992 Beiträge seit 2005
vor 18 Jahren

Also anders klappt das nicht?
Das ich einen Thread mache, da ne Klasse instanziere, die solche Arrays behandelt?

49.485 Beiträge seit 2005
vor 18 Jahren

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

P
939 Beiträge seit 2003
vor 18 Jahren

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

S
8.746 Beiträge seit 2005
vor 18 Jahren

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....

P
939 Beiträge seit 2003
vor 18 Jahren

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

S
8.746 Beiträge seit 2005
vor 18 Jahren

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.

4.221 Beiträge seit 2005
vor 18 Jahren

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...

Q
Quallo Themenstarter:in
992 Beiträge seit 2005
vor 18 Jahren

Kann mich nicht entsinnen, dass bei ding.wav frequenz und tonlänge frei wählbar ist! g

Grüße Christoph

4.221 Beiträge seit 2005
vor 18 Jahren

Lach ok ich dachte Du brauchst einfach einen Beep...

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...