Verallgemeinerungsproblem bei Delegates
-
So liebe Gemeinde, folgendes Problem liegt vor,es existieren folgende Files.
public interface ISessionable { void StartSession(); void StopSession(); void InitSessionTimer(Timer timer,EventHandler handler);//hier herrscht das Problem, siehe Unten. }
public class SessionObject { public ISessionable Object { get; private set; } public SessionObject(ISessionable isessionable) { this.Object = isessionable; } }
public class Session { public SessionObject SessObject { get; private set; } public Session(SessionObject obj) { this.SessObject = obj; } public void StartSessionManagment(ISessionable isse,Timer tim,EventHandler handler) { isse.InitSessionTimer(tim, handler); isse.StartSession(); } public void StopSessionManagment(ISessionable isse) { isse.StopSession(); } }
Meine Frage lautet.Wie kann ich in dem Interface die
InitSessionTimer
Methode so gestalten, das sie jeden Typ von delegate annimmt.Gibt es da Basisklasse?Weil in meiner Sessionklasse, möchte ich das auf den nur gezeigten delegaten Typen begrenzen, also ausschließlich
delegate void Funktion(object sender,EventArgs)
Ich hoffe es ist verständlich gewurden.**
EDIT:Nochmal die Session Klasse aktualisiert.**
-
Hmmm ich habe gerade mitbekommen, das System.Delegate die Oberklasse ist, zumindest scheint es mir so.
Nun habe ich aber ein anderes Problem, ich möchte an dem Timer.Tick Event meinen Delegaten anmelden, ungefähr so hier:
class Client : ISessionable { private Timer timer; #region ISessionable Members public void InitSessionTimer(Timer timer,Delegate handler) { this.timer = timer; timer.Tick +=new EventHandler(handler); } //restlichen funktionen #endregion }
Leider bekomme ich die Fehlermeldung das handler eine Variable ist und Versucht wird wie eine Methode zu benutzen, was ja auch korrekt ist, aber wie komme ich nun an die bei Delegate liegende Funktion? um sie an dem Tick Event anzumelden?
-
Leider muss ich das nochmal hochpushen. Hat keiner eine Lösung?witte du vielleicht? Du machst das doch schon länger
-
Was spricht gegen folgendes?
public interface ISessionable { void StartSession(); void StopSession(); void InitSessionTimer(Timer timer, EventHandler handler); }
und dann
class Client : ISessionable { private Timer timer; #region ISessionable Members public void InitSessionTimer(Timer timer, EventHandler handler) { this.timer = timer; timer.Tick += handler; } //restlichen funktionen }
-
Meine Frage lautet.Wie kann ich in dem Interface die InitSessionTimer Methode so gestalten, das sie jeden Typ von delegate annimmt.Gibt es da Basisklasse?
Meine Frage ist dann aber: Wenn jeder Typ von Delegat zugelassen ist, woher und wie übergibst Du dann unterschiedliche Parameter beim Aufruf des Delegaten?
Ein Delegat speichert eine Funktion (salop gesagt), welche zum späteren zeitpunkt aufgerufen werden kann. Dabei ist die Signatur fix (pro Delegat).
Simon
-
Korrekt,ich halte mich einfach an die MS-EventHandler Konvention. Jeder Delegate muss somit
void funktion(oject sender, EventArgs e)
"sein".Natürlich schränkt das in einer gewissen form ein,weil ich keine Rückgabewerte behandeln kann, auf der anderen Seite kann ich so auf einem relativ hohem allgemein niveau arbeiten.Hab ich mir zumindest so vorgestellt.
-
Hmm die Lösung von hajb hat mir zwar die Compilerfehler beseitigt, aber ich erziele nicht das gewünschte Ergebnis.
Hier nochmal die Aktuelle Struktur.class Client : ISessionable { private Timer timer; public void test(object sender, EventArgs e) { Console.WriteLine("Sessionmanager worked"); } #region ISessionable Members public void InitSessionTimer(Timer timer,EventHandler handler) { this.timer = timer; this.timer.Interval = 1000; timer.Tick += handler; } public void StartSession() { this.timer.Start(); } public void StopSession() { this.timer.Stop(); } #endregion }
class Program { static void Main(string[] args) { Client cl = new Client(); Session sess = new Session(new SessionObject(cl)); sess.StartSessionManagment(cl, new Timer(), cl.test); Console.ReadKey(); } }
So normaler Weiße sollte doch jetzt aller 1sec auf der Konsole "SessionManager worked" ausgegeben werden, oder irre ich mich?
-
Mit dem Timer aus System.Windows.Forms benötigst Du einen Message Loop, den hast Du aber nicht.
Benutze System.Threading.Timer und Du benötigst keine Message Loop mehr.
Simon
-
Ausserdem:
Falls der Client nur einen Delegaten (den den Du bei InitSessionTimer mitgibst) hat und aufruft, kannst Du dein Tick Event auch intern im Client abbonieren, den Delegaten (was auch immer für einer, da bist Du frei in der Signatur) in Client als Member speichern und dann im Tick Handler diesen Delegaten aufrufen.Falls mehrere Delegaten sich anmelden können, empfehle ich einfach dem Client ein Event zu verpassen.
Simon
-
@theta: Da haste natürlich recht.Problem beim system.Threading.Timer ist das man bei diesem keinen Tick-Event anmelden kann. Zumindest habe ich sowas nich gefunden, kannste da vielleicht mal zeigen was du meinst?
-
Was genau soll ich zeigen?
Die Benutzung von System.Threading.Timer? Es gibt bei MSDN ein Bsp.Simon
-
Nein ich meinte, ob/wie man an einem System.Threading.Timer ein Event anmelden kann, weil soweit ich gesehen habe, gibt es da kein Tick-Event.
-
Dafür ein Callback Delegat (wird beim CTOR übergeben).
Simon
-
Ok gut das hab ich hinbekommen, nun eine wesentlich wichtigere Frage, wie kann ich das Ding starten?Die MSDN ist da nicht gerade sehr aussagekräftig.Eine .Start() Methode gibts da ja nicht.Oder wird der automatisch beim Erzeugen gestartet?
-
Ja. Lies doch msdn mal ein wenig genauer....
-
Ja ok habs gefunden
Er wird eingeschaltet sobald ich ihn erzeuge.