Statischer Methodenaufruf von anderer Klasse

  • C#

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Statischer Methodenaufruf von anderer Klasse

    Hallo in die Runde,

    ich habe sowas wie eine Netzwerkschnittstelle geschrieben, die in einer statischen Methode ausgeführt wird. In dieser statischen Methode befindet sich eine while(true){//Netzwerkkram}, die sich eigentlich nur beenden lässt, wenn das Programm geschlossen wird (das soll so sein). Jetzt habe ich diese Netzwerkschnittstelle soweit ausgelagert und wollte diese von einer anderen Klasse aufrufen. Weil es sich um eine statische Methode handelt wäre der Aufruf hiermit erledigt gewesen NetzwerkKlasse.statischeMethode();

    Mein Problem ist jetzt folgendes, ich kann diese statische Methode aufrufen, jedoch wird aus irgendwelchen Gründen, die Endlosschleife in der NetzwerkKlasse durchbrochen, sodass ich wieder bei meiner "Programm Klasse" (die Klasse die den Aufruf NetzwerkKlasse.statischeMethode(); beinhaltet) lande. Warum ist das so und wie kann man das verhindern?

    Wenn ich in der NetzwerkKlasse eine Main Methode implementiere und dann exakt die selbe statische Methode aufrufe funktioniert alles, die while(true){//Netzwerkkram} beleibt solange, wie ich das Fenster geöffnet habe. Ich will diesen Aufruf aber gerne von einer anderen Klasse aus aufrufen...

    Ich bin für jede Antwort dankbar!

    VB.neter0101 schrieb:

    Mein Problem ist jetzt folgendes, ich kann diese statische Methode aufrufen, jedoch wird aus irgendwelchen Gründen, die Endlosschleife in der NetzwerkKlasse durchbrochen
    kann eigentlich nur durch eine Exception geschehen - oder du hast selbst was in die Schleife geschrieben, was die Schleife verlässt (ich nehme mal an, das meinst du mit "durchbrechen").
    Von woanders kann man diese Methode auch nicht aufrufen - jedenfalls nicht im selben Thread.
    Ok, dann wäre interessant, wie man das beheben kann oder geht das nicht? Ich meine wo ist der Unterschied es ist doch alles statisch....

    Die Methode ist auszugsweise etwa so gestaltet:

    C#-Quellcode

    1. public static void NetzwerkMethode()
    2. {
    3. //...
    4. var tmp = Task.Run(() =>
    5. {
    6. // ...
    7. while (true)
    8. {
    9. //...
    10. }
    11. });
    12. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB.neter0101“ ()

    Das ist das Stückchen Code was ich meine, jetzt einmal etwas mehr im Detail. Davor stehen ein paar Konfigurierungsaufrufe, die den Kohl aber nicht fett machen...

    C#-Quellcode

    1. var tmp = Task.Run(() =>
    2. {
    3. using (var registry = new CachedSchemaRegistryClient(schema))
    4. using (var cons = new Confluent.Kafka.ConsumerBuilder<Confluent.Kafka.Null, GenericRecord>(conf)
    5. .SetValueDeserializer(new AvroDeserializer<GenericRecord>(registry).AsSyncOverAsync())
    6. .Build())
    7. {
    8. cons.Subscribe(topic);
    9. while (true)
    10. {
    11. // ...
    12. }
    13. }
    14. });


    Warum kann ich das nicht, obwohl es in einer statischen Methode definiert ist, von einer anderen Klasse aus aufrufen. Schafft man das überhaupt, oder ist das hier einfach nicht möglich, weil?

    VB.neter0101 schrieb:

    obwohl es in einer statischen Methode definiert ist
    Probier mal eine nicht statische Klasse.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @VB.neter0101 Dann mach aus der statischen Prozedur testweise eine nicht statische Prozedur.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jo, habich ausprobiert: Task.Run() in dieser Weise ausgeführt startet einen NebenThread.
    wieder zu post#2:
    Aus der while(true)-Schleife kommt er nur heraus, wenn dafür etwas gecodet ist, oder wenn eine Exception auftritt.
    Kann sein, dass die Exception verschluckt wird, weil die Choose im NebenThread läuft.
    Ja, so siehts aus: Exceptions im Nebenthread werden verschluckt, wenn als Release kompiliert ist.

    VB.neter0101 schrieb:

    aber warum sollte das denn funktionieren?
    Möglicherweise.
    Denk mal über Debug-Ausgaben nach, damit Du die Stelle des Abbruchs findest.
    Und nun anders herum:
    Pack die statische Methode in eine statische Klasse.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe jetzt mal ein paar Console.WriteLine(); Befehle eingebaut, es scheint so zu sein, als dass er den Aufruf von Task.Run(() ... überhaupt nicht ausführt, aus irgendwelchen Gründen. Leider komme ich in den Run Teil auch via Debugging nicht rein. Das Ganze läuft bei mir als .Net Core...

    Hier nochmal eine kleine Übersicht meines Settings:

    C#-Quellcode

    1. ​namespace A
    2. {
    3. class NetzwerkKlasse
    4. {
    5. static void Main(string[] args)
    6. {
    7. Netzwerk(); // läuft
    8. }
    9. public static void Netzwerk()
    10. {
    11. var tmp = Task.Run(() =>
    12. {
    13. using (var registry = new CachedSchemaRegistryClient(schema))
    14. using (var cons = new Confluent.Kafka.ConsumerBuilder<Confluent.Kafka.Null, GenericRecord>(conf)
    15. .SetValueDeserializer(new AvroDeserializer<GenericRecord>(registry).AsSyncOverAsync())
    16. .Build())
    17. {
    18. cons.Subscribe(topic);
    19. while (true)
    20. {
    21. // ...
    22. }
    23. }
    24. });
    25. }
    26. }
    27. }
    28. namespace A
    29. {
    30. class Programm
    31. {
    32. static void Main(string[] args)
    33. {
    34. NetzwerkKlasse.Netzwerk(); // läuft nicht bzw. führt Task.Run(() nicht aus
    35. }
    36. }
    37. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB.neter0101“ ()

    Du await-est den Task nicht. Ohne await wird der Task parallel gestartet und läuft auch parallel zum Rest deines Programms weiter. Die Main Methode läuft also direkt weiter ohne auf das beenden des tasks und der Schleife zu warten. Das Programm beendet sich dann auch direkt danach. Mach die Main Methode und Deine Netzwerk Methode async und awaite den Task.
    Danke für eure Hilfe, die Lösung ist tatsächlich nur ein tmp.Wait(); gewesen, dass hinter den Task Aufruf geklemmt werden musste, jetzt kann ich den gleichen Code auch von einer anderen Klasse ausführen. Danke sehr!

    @Dksksm, danke für den Hinweis, ich schaue da mal rein!

    Ich bin kein Freund dieser ganzen asynchronen Geschichten, nutzt Ihr das aktiv? Ich finde das eher hinderlich...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB.neter0101“ ()

    shad schrieb:

    Mach die Main Methode und Deine Netzwerk Methode async und awaite den Task.
    Ja, das ist die übliche Vorgehensweise - damit erreicht man bestimmte Dinge.
    Aber ich weiss nicht, ob das beim TE relevant ist, also warum sollte er das tun?
    Es soll im NebenThread eine Endlossschleife laufen - ich denke nicht, dass es viel Sinn hat, das Ergebnis einer Endlosschleife zu Awaiten.

    VB.neter0101 schrieb:

    Ich bin kein Freund dieser ganzen asynchronen Geschichten, nutzt Ihr das aktiv?
    Ich benutze das nur, wenn es unumgänglich ist.
    Weil natürlich führt Nebenläufigkeit immer zu einer erheblichen Verkomplizierung.
    Mit allen Nachteilen, die Komplexität eben hat.