Allg. Frage zu Delegates und Callbacks, etc

Hallo,

ich habe eine allgemeine Frage zu Delegates, Callbacks, Threads. Ich habe zu den Themen vieles gelesen; aber irgendwie versteh ich immer nur Bahnhof und die immer dazu aufgeführten Beispiele erscheinen mir nicht sinnig und einleuchtend.

Ich bräuchte mal irgendwie ein richtiges Beispiel, wo (mir *grins*) klar wird, wo sowas angewendet wird, warum und wieso es so am besten gemacht wird und nicht anders (ich hatte schon solche Probleme am Anfang mit Interfaces, bis ich mal ein Superbeispiel von jemanden bekam). Bitte kein Beispiel wie: Wir nehmen Klasse A und B und machen da dazwischen irgendwo ein Delegate. Ich brauch was handfesteres.

Ich programmier schon lange in C#, aber die Sachen sind vor mir noch verschlossen und versuchte das immer zu umgehen :wink:))

Mir geht es darum: Ich habe einige Klassen, wo in einigen Methoden bestimmte Aktion abgearbeitet werden (Werte berechnen, Laden von Daten etc). Jetzt möchte ich dem Benutzer gerne einen Fortschrittsbalken zeigen, wo er sehen kann, wie weit die Berechnungen (sprich Schleifen) schon fortgeschritten sind damit er weiß, es ist noch Zeit für 'ne Zigarette :smile:

Klar möch ich die Fortschrittsbalken in einer eigenen Klasse in einer Userform generieren, aber er braucht ja auch Infos. Der Balken soll möglichst universell einsetzbar sein.

Für Hilfe wär ich Euch dankbar.

gruß Olli

Hi!

Wie Du sehr richtig schreibst, muss Dein Fortschrittsbalken ja irgendwie weiter geschaltet werden. Dafür eignen sich z.B. solche delegates in Verbindung mit Ereignissen hervorragend.

Beispiel: Deine Klasse, die Daten lädt, will signalisieren, dass ein Stückchen Daten geladen wurde. Dazu kann sie ein Ereignis definieren:

public event EventHandler DatenstueckGeladen;

Damit hätte man auch schon einen delegate verwendet, nämlich indem man geschrieben hat, dass das Ereignis DatenstueckGeladen eine Funktion vom Typ EventHandler aufruft.

EventHandler ist definiert als

public delegate void EventHandler(object sender, EventArgs e);

, also eine Funktion, die 2 Parameter erwartet: Ein object und einmal EventArgs.

Wenn Du Dich nun an der Stelle, wo Du diese Datenlade-Klasse verwenden willst, für besagtes Ereignis DatenstueckGeladen registrieren willst, dann erfolgt das ja bekanntlich mit

meinDatenLader.DatenstueckGeladen += new EventHandler(meineBenachrichtigungsFunktion);

wobei meineBenachrichtigungsFunktion dann genau die oben angegebene Signatur haben muss, also z.B. so aussehen kann:

protected void meineBenachrichtigungsFunktion(object sender, EventArgs e)
{
 progressBar1.Increment(1);
}

In diesem Fall werden die 2 Parameter nicht verwendet, aber Du kannst Dir sicherlich leicht vorstellen, dass es bei Ereignissen Sinn machen kann, an den EventHandler (also den delegate, der zur Behandlung des Ereignisses aufgerufen wird) weitere Infos zu übergeben, die dann genutzt werden können.

Jetzt ein bisschen klarer oder immer noch nebulös? :smile:

Gruß,
Martin

Hi Martin,
dein Beispiel hat bei mir einen leichten Aha-Effekt ausgelöst, aber trotzdem ists noch etwas nebulös :smile:

Paß auf, die meisten Beispiele die ich finde sind immer nach dem gleichen Schema aufgebaut:

namespace PARTool
{
 delegate bool meinDelegate(int wert);

 class Class1
 {
 public bool Methode1(int wert)
 {
 if(wert \> 0)
 return true;

 return false;
 }
 }

 /\*-------------------------------------------------------------------\*/
 class Hauptklasse
 {
 public void DelegateTest()
 {
 meinDelegate testdel = new meinDelegate(new Class1().Methode1);

 bool ergebnis = testdel(12);
 }
 }
}

So, das hab ich mal rasch selbst entworfen :smile:, aber die Beispiele laufen immer nach dem o.g. Code ab. Was ich mich dann immer nur frage, warum soll ich so ein Delegate machen, wenn ich gleich ein Objekt von der Klasse class1 generieren kann?

Soll der Sinn von den Delegates sein, daß ich zum Beispiel der Klasse1 eine Methode von Klasse4 übergeben kann, ohne das in Klasse1 eine Instanz von Klasse4 erstellt wird?

Gruß Olli

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Der Sinn & Zweck von Delegates ist, dass man damit Aufgaben delegieren kann (daher wohl auch der Name).

Bei „normalen“ Methodenaufrufen gibt man Parameter mit, die steuern, wie die aufgerufene Methode arbeitet.
Dabei kann man aber halt letztlich nur die vorgesehenen Funktionalitäten ansteuern, eine Erweiterung um neue Funktionalitäten ist damit nicht möglich.
Delegates/Callbacks dienen dazu, auch Funktionen als Parameter mitgeben zu können. Und was dann in einer solchen übergebenen Funktion gemacht wird, das bleibt wiederum ganz Dir überlassen, nicht dem Entwickler, der die aufgerufene Methode implementiert hat.

Das trifft auf EventHandler für beliebige Ereignisse genauso zu wie für Callbacks als Funktionsparameter.

In deinem Beispiel ist der Witz ja gerade der, dass Du eine beliebige Methode, die die geforderte Signatur hat, als Parameter mitgeben kannst (beim new meinDelegate()).
Klar, Du kannst auch so eine Klasse Class1 erzeugen, aber der Clou ist eben, dass genau die Methode Methode1 dieser erzeugten Klasseninstanz aus der Hauptklasse heraus aufgerufen wird.

Noch ein ganz elementares Beispiel: Ein Button wird geklickt.
Was soll dann passieren?
Weil man es eben nicht sagen kann, was in jedem Fall beim Klick auf die Instanz eines Buttons passieren soll, muss man dort einen Delegate verwenden, der dann aufgerufen wird:

myButton1.Click += new EventHandler(myButton1\_Click);

Damit hat man dann das Auslösen des Ereignisses von der eigentlichen Behandlung entkoppelt und Deine Methode myButton1_Click wird aufgerufen, egal, wo sie ist und was sie konkret macht.

Martin