Laden...

Programmierkonstrukt für das Ausführen von beliebigen Methoden mit unterschiedlichen Parametern

Erstellt von Bunnychecker vor 11 Jahren Letzter Beitrag vor 11 Jahren 2.130 Views
B
Bunnychecker Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren
Programmierkonstrukt für das Ausführen von beliebigen Methoden mit unterschiedlichen Parametern

Hallo,

ich bin mir nicht sicher wie man folgendes Problem löst.

Ich habe eine Klasse in der es verschiedenste Methoden mit unterschiedlichen Parametern gibt. Die Methoden machen alle nur kleinere Berechnungen.

Nun möchte ich aufbauend auf dieser Klasse eine Logikschicht oben aufsetzen, die mir diese Methoden nun zu bestimmten Zeitpunkten (z.B: 12:53 Uhr) aufruft.

Ich bräuchte dann einen universellen Delegaten oder wie soll ich das Problem lösen?

LG

1.002 Beiträge seit 2007
vor 11 Jahren

Hallo Bunnychecker,

du kannst dein Problem mit Hilfe verschiedener Ansätze lösen.*Einerseits kannst du die gewünschten Methoden aufrufen, nachdem eine – vom jetzigen Zeitpunkt ausgehende – Zeitspanne abgelaufen ist. Stichwort: Timer. *Andererseits kannst du periodisch, also z.B. alle 5 Minuten, überprüfen lassen, ob du dich in deinem angestrebten Zeitfenster befindest. Weiterhin musst du überprüfen, ob die Methoden nicht bereits ausgeführt worden sind; das regelst du am besten über ein "Ausgeführt"-Flag. Sind beide Bedingungen erfüllt, führst du die Methoden aus. Wurden diese erfolgreich ausgeführt, setzt du das "Ausgeführt"-Flag auf true.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

B
Bunnychecker Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren

Danke dir für deine Antwort.

Das war sicher aus meinem Beitrag nicht ganz herauszulesen. Mir ging es dabei vorallem darum, wie ich die unterschiedlichen Signaturen der Methoden in einen Container packe, sodass das Programm dann, wenn der Timer abgelaufen ist oder die zyklische Abfrage ausgeführt werden soll, auch alle Parameter für diesen Methodenaufruf vorhanden sind.

1.002 Beiträge seit 2007
vor 11 Jahren

Hallo Bunnychecker,

das ist jetzt ein wenig generell. Mit so wenigen Informationen kann ich dir natürlich nicht sagen, wie du es am besten anstelltst, dass "auch alle Parameter für diesen Methodenaufruf vorhanden sind". Ob du diese in Dateien zwischenspeicherst oder sonst wo ablegst, musst du selbst anhand deines konkreten Szenarios entscheiden.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

B
Bunnychecker Themenstarter:in
224 Beiträge seit 2009
vor 11 Jahren

    class Class1
    {
        public void Method1(string s)
        {
        }

        public void Method2(int i)
        {
        }

        public void Method3(double d, string str)
        {
        }

        /// Weitere Methoden mit unterschiedlichen Signaturen
    }


Nun hätte ich gerne solch eine Liste:

Element0: Methode1(string1)
Element1: Methode3(2.5, string2)
Element2: Methode2(12)
...

Und immer wenn der Timer abgelaufen ist, soll er das nächste Element in der Liste (keine Queue, da die veränderlich bleiben soll) abarbeiten.

656 Beiträge seit 2008
vor 11 Jahren

Ich bräuchte dann einen universellen Delegaten

Wie wärs mit Action?
In Verbindung mit Lambda Expressions könntest du damit einfach eine Liste befüllen.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo Bunnychecker,

ich denke, das geht mit Delegaten (alleine) nicht, sondern man muss die Methode per Reflection aufrufen, denn da kann man die Parameter als Object-Array übergeben. [EDIT]Vorausgesetzt, man will eine abgeschlossene Lösung, die mit beliebigen Parametertypen funktioniert, ohne dass man für jede (weitere) Parameterkombination eigene(n) Adapter(methode) oder zumindest einen entsprechenden Lambda-Ausdruck erstellen muss.[/EDIT] Reflection zu verwenden, verlagert die Typprüfung natürlich zur Laufzeit.

Mit anderen Worten, man merkt sich in der Queue, a) den Delegaten oder gleich die MethodInfo der aufzurufenden Methode, b) das Objekt, für das die Methode aufgerufen werden soll und c) die Parameter der Methode als Object-Array. Dann hat man alles beisammen für den Aufruf per Reflection.

Du solltest auf passende Thread-Titel achten. Wenn es dir nicht auf den Zeitpunkt sondern die Art des Aufrufs ankommt, sollte das schon aus dem Titel hervorgehen ==> geändert

herbivore

PS: Jetzt verstehe ich, glaube ich, wie BhaaL das meint. Man kann natürlich auch Lambda-Ausdrücke in die Queue stellen, wobei der Lambda-Ausdruck selbst keine Parameter bekommt, sondern alle Parameter im Rumpf des Lambda-Ausdrucks direkt an den eigentlichen Methodenaufruf übergeben werden. Deshalb kommt man dann mit dem parameterlosen (nicht generischen) Action-Delegaten aus. Die Parameter kommen dann beim späteren Aufruf - sofern es sich nicht um Literale handelt - aus captured variables, was etwas Vorsicht erfordert, damit auch tatsächlich die gewünschten Werte übergeben werden, siehe Von einem Thread auf einen anderen zugreifen [und captured variables].

799 Beiträge seit 2007
vor 11 Jahren

Wenn du die Typsicherheit behalten möchtest, könntest du das auch per Adapter-Pattern lösen.

Dann würdest du für jede Methode die du aufrufen möchtest, eine Adapter-Klasse schreiben die mit den nötigen Parametern der Methode befüllt wird.

Eine jede Adapter-Klasse muss dann noch ein Interface der Form:


public interface IExecutable 
{
    public void Execute();
}

implementieren. Für deine Methode 3 würde dann ein Adapter z.B. so aussehen:


public class Method3Adapter : IExecutable
{
    public double D { get; set; }
  
    public String Str { get; set; }

    public void Execute() {
       // woher du dann die konkrete Instanz deines Objektes nimmst musst
       // du dir überlegen, hängt davon ab ob es mehrere Instanzen sein sollen,
       // verschiedene Typen sein, etc.
       deineInstanz.Method3(D, Str);
    }
}

Und solche Objekte speicherst du in einer Liste die du dann periodisch aufrufst.

PS: Die Lambda-Lösung würde ich vermeiden. Sie sieht bestimmt im Code sehr elegant aus, ist aber gleichzeitig mit viel Vorsichtz genießen wie herbivore schon ausgeführt hat.
Das oben angeführte Pattern ist zwar nicht so sexy wie Closures aber viel einfacher in Punkto Seiteneffekte sowie Scope zu durchschauen.

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl
2.079 Beiträge seit 2012
vor 11 Jahren

Aufbauend auf den Ideen von der-schlingel und herbivore:

Beidem Adapter, kann man die nicht auch viel einfacher so gestalten, dass sie drei Eigenschaften vom Typ MethodInfo (Die Methoden-Infos), object (Die Referenz, fals eine vorhanden ist) und object[] (für alle Parameter, wenn es keine gibt, ist das Array einfach leer)

Der Klasse werden die Informationen dann übergeben, oder man baut einen Konstruktor, der als Parameter neben den beiden anderen Eigenschaften direkt die betroffene Methode übernimmt. Dafür kann man dann ja passende Delegaten schreiben und den Konstruktor entsprechend überladen.
Die Überprüfung der Parameter müsste sich ja mit den Informationen von MethodInfo relativ einfach realisieren lassen.

Ich hab das noch nicht ausprobiert, aber so weit ich mich an den Inhalt von MethodInfo erinnern kann, gab es da eine Methode, die neben der Referenz ein Array vom Typ object annimmt und dann die, durch die Referenz von MethodInfo dargestellte, Methode ausführt.

Wenn ich falsch liege lasse ich mich gerne belehren, aber die Idee mit dem Adapter gefällt mir, ich glaube ich schreibe mir gleich mal Einen, der sowas tut^^ Wenn er funktioniert, kann ich ihn ja hier zeigen.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

799 Beiträge seit 2007
vor 11 Jahren

Das ist dann eine Kombination von Herbivores und meiner Idee.

Sollte aber so machbar sein.

As a man thinketh in his heart, so he is.

  • Jun Fan
    Es gibt nichts Gutes, außer man tut es.
  • Erich Kästner
    Krawutzi-Kaputzi
  • Kasperl