Managed C++ bzw. C# - Zeitkritische Anwendung



  • Hi,

    ich stehe momentan vor der Entwicklung einer zeitkritischen Anwendung, deren Oberfläche geskinnt werden soll und die nur unter Windows laufen muss. Daher dachte ich, ich könnte ja .net verwenden, weil das Skinning damit angeblich viel einfacher sein soll als mit purer WinAPI.

    Das Problem ist nur, dass bei .net ja jederzeit der GC zuschlagen kann und man kann ihn ja soweit ich weiß nicht wie in Java auch von Hand vor zeitkritischen Stellen (wo er auf keinen Fall zuschlagen darf) aufrufen.

    Wie seht ihr die Sache? Im Prinzip ist das Ganze ja ähnlich wie einfach Spiel und dort verwendet man ja genau aus diesem Grund kein .net (abgesehen davon, dass nur Linuxspiele gute Spiele sind :D). Gibt es eine Möglichkeit, den GC besser zu kontrollieren oder sollte ich wieder nativen ("unsicheren" ;)) C++-Code verwenden?

    Die sonstigen Features von C#/.net brauche ich nicht bzw. ich vermisse die fehlenden Features von C++ (Pointer, Mehrfachvererbung), es wäre also nur wegen der einfachen Erstellung der GUI.

    ChrisM



  • ChrisM schrieb:

    Das Problem ist nur, dass bei .net ja jederzeit der GC zuschlagen kann und man kann ihn ja soweit ich weiß nicht wie in Java auch von Hand vor zeitkritischen Stellen (wo er auf keinen Fall zuschlagen darf) aufrufen.

    Ist zwar etwas OT, aber: Der Aufruf von "System.gc();" in Java löst den GC nicht unbedingt aus. Das ist nur ein "empfohlenes Verhalten", an das sich aber kein JVM Hersteller zwingend halten muss. Diese Methode kann auch gar nichts machen. Mit anderen Worten: Die System.gc-Methode ist nutzlos da ihr Verhalten nicht zwingend definiert ist. Man kann auch in Java nicht 100%ig den GC zu einem bestimmten Zeitpunkt auslösen.



  • naja, Zeitkritisch ist ein weit dehnbarer Begriff.

    Um was für ein Projekt handelt es sich denn ?

    Wenn deine Anwendung wirklich so Zeitkritisch ist, solltest du vielelicht C++ nehmen. Wenn du sowieso C++ lieber magst, ist das für dich ja auch kein Porblem.
    Fürs Skinning gibt es Libs zum Kaufen. Das erleichtert auch die Arbeit.



  • Hallo,

    AndreasW schrieb:

    Fürs Skinning gibt es Libs zum Kaufen. Das erleichtert auch die Arbeit.

    Libs? ... nochmal OT: könntest Du da vielleicht ein paar Quellen angeben? Die Skin-Editoren, die ich bislang gefunden habe, beschränken sich immer auf elementare Control-Klassen.



  • ChrisM schrieb:

    Das Problem ist nur, dass bei .net ja jederzeit der GC zuschlagen kann und man kann ihn ja soweit ich weiß nicht wie in Java auch von Hand vor zeitkritischen Stellen (wo er auf keinen Fall zuschlagen darf) aufrufen.

    Kann man schon. Über System.GC kannst du auf den GC zugreifen und finalizer an- und abmelden, eine Bereinigung durchführen...
    Siehe aber Gregors Post.

    Wie seht ihr die Sache? Im Prinzip ist das Ganze ja ähnlich wie einfach Spiel und dort verwendet man ja genau aus diesem Grund kein .net

    Ob die Gründe wirklich so gut sind?! Ich bezweifle es inzwischen sehr. Früher mögen sie besser gewesen sein.

    Die sonstigen Features von C#/.net brauche ich nicht bzw. ich vermisse die fehlenden Features von C++ (Pointer, Mehrfachvererbung), es wäre also nur wegen der einfachen Erstellung der GUI.

    Mal ne dumme Frage: Warum benutzt du nicht einfach die Sprache, die dir mehr zusagt? Wenn du unbedingt mit Adressen h4x0rn willst, dann tu es doch, wenn dir die Referenzen nicht reichen. Unsafe Code kannst in C# aber genauso schreiben. Ebenso wie in managed C++ der GC zuschlagen kann (der bei gen0 Collections i.d.R. <= 1ms braucht).

    Also hast du irgendwie überhaupt keine guten Gründe für oder gegen was und kannst gleich das nehmen, was dir gefällt.



  • Wenn du C++.net nimmst kannst du die üblichen C++-Sprachelemente und jede beliebige C++-Lib mit dem .net-Framework zusammen verwenden.

    Eine weitere Möglichkeit, wenn du .net einsetzen willst und nativen (in C++ entwickelten) Code ausführen willst wäre, diesen Code in DLLs auszulagern und ihn mit System.Runtime.InteropServices.SystemDllImport() aus deiner .net-Anwendung aufzurufen.

    Du kannst aber auch dein ganzes Programm in .net schreiben und mit einem bestimmten Tool zu nativen performanten WIN32-Code kompelieren.

    PS: Der GC ist der letzte Grund dafür dass .net langsamer als unmanaged C++ ist.



  • Langsamer nicht, aber wenn es um zeitkritische Anwendungen geht, darf die Verzögerung nicht hoch sein.
    Ob ein GC das wirklich sehr stört, naja ist eher fraglich.
    Das lässt sich aber in beiden Sprachen auch so bewerkstelligen, indem man für die entsprechenden Bereiche die Objekte auf dem unmanaged Heap legt.



  • Hi,

    ob .net langsamer ist als nativer C++-Code spielt für mich keine Rolle, es gibt nur verschiedene Abschnitte in der Anwendung, in denen der GC auf keinen Fall zuschlagen darf. 1ms Verzögerung wäre dort natürlich noch auszuhalten, aber alles größer 5ms ist schon viel zu viel.

    Wenn ihr noch Ideen zum Skinning in C++ (nativ) habt, könnt ihr sie gerne noch hierreinposten, eine (kostenlose) Lib wäre wirklich nicht verkehrt, denn so schicke Controls mit Owner Draw sehen viel besser aus als die Windows-Standardcontrols, sind aber von Hand unheimlich viel Arbeit.

    ChrisM



  • Also ich würde .net nehmen. Hab oben ja genug Möglichkeiten das mit unmanged Code zu verbinden genannt.

    Bei .net hast du alle Möglichkeiten was das Userinterface angeht. Und zu dem noch alles ziemlich "mundgerecht".

    Für Userinteraces in unmanaged C++ kenn ich nur die MFC. Ob die free ist weiß ich nicht, aber auf jeden Fall ist die bei Visual Studio dabei.



  • Ich weiss nicht, ob es auch mit dem alten C++.Net 2003 schon geht, aber es gibt auch die Möglichkeit, .Net-Objekte direkt auf dem Stack zu halten. Dort hat der GC aber nix zu suchen. Die Objekte werden sofort freigegeben, wenn sie den Gültikeitsbereich verlassen. Das wäre vielleicht eine gute Lösung.

    PS: Falls ich Mist geredet habe, werde ich gerne aufgeklärt 👍 !



  • Ich habe auch dieses Gerücht gehört. Leider ändert es nur am grundsätzlichem Problem nichts. Der GC kann trotzdem anspringen, wann es ihm passt.
    Könnte ja sein, dass gerade so eine Funktion gut passt, wo er eh nichts aufm Heap arbeitet. Es gibt so genannte safe-points, wo der GC weiß, was in den Registern ist und wann und wo was aufm Heap gemacht wird. Das ist wichtig, damit er sich Zeitpunkte aussuchen kann, wo er nebenbei seinen GC machen kann, ohne die anderen Threads zu blocken.

    Wenn das nicht wäre, könnte man ja einfach vorher ne full collection durchführen und darauf vertrauen, dass er erstmal Ruhe gibt.

    In der Praxis kann man das auch, aber niemand garantiert dir, dass das im .Net Framework 98734.4.2.5 SP 18 immer noch so ist. Es ist einfach nicht empfehlenswert, irgendein Verhalten für den GC anzunehmen.



  • Ich habe auch dieses Gerücht gehört.

    Ein Gerücht ist es nicht einmal. Steht glaub ich sogar irgendwo im C++/CLI Standard (aber das heisst eigentlich, dass man .Net 2.0 verwenden müsste, also lassen wir diese Option besser mal beiseite).

    Wenn es denn wirklich auf jede Millisekunde ankommt (das gibts halt ab und zu mal 😃 ), dann ist wohl wie gesagt ein Mix aus Managed/UnManaged C++ und Assembler am besten. Die ganz kritischen Funktionen kann man dann ja mit Assembler schreiben und aus der .Net-Gui direkt aufrufen. Von P/Invoke und DllImport würde ich grundsätzlich mal abraten, weil dabei viel Zeit verloren gehen kann, wenn marshaling zum Einsatz kommt.



  • Warum geht das skinnen denn bei .NET Framework einfacher? Da muss man sich doch auch entweder fertige Komponenten runterladen oder mühsam selbstschreiben.

    Außerdem sehen Windows Standard Controls besser aus als geskinnte.



  • Im .net-Framework hast du für jedes Windows-Standart-Control eine Klasse, die du entweder direkt so verwenden oder in eine eigene Klasse ableiten kannst und dort hast du dann nahezu unbegrenzte Möglichkeiten was die Erweiterung und das Design angeht.

    Edit: Was sollen die Sternchen da?



  • Der GC geht doch nur ans Werke, wenn es grade nix zu schaffen gibt, habe ich immer gedacht. Daher wird der nicht ins Gewicht fallen!



  • Irgendwas hat das Programm immer zu tun und sei es auf die Aktion des Anwenders zu warten. Daher schlägt der GC dann zu wenn er denkt das so wenig zu tun sei das eine Garbage-Collection niemand bemerken würde. Und es ist gut möglich das der GC grade in dem moment denkt das niemanden seine Tätigkeit stört, wenn eine Verzögerung von ein paar Millisekunden unerwünscht ist.


Anmelden zum Antworten