Autor Beitrag
Greenberet
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: So 27.10.13 21:14 
Hallo,

ich habe derzeit ein Problem mit dem erstellen eines Objektes.

Die Klasse (AXLAPIService) wurde aus einem WSDL generiert. Der Code der Datei ist ca 10MB groß und umfasst 281665 Zeilen generierten codes.

Im Anhang findet ihr die Klasse um euch ein Bild machen zu können.

Das Problem: Das Erstellen eines Objektes dauert ~1 Minute. Nachdem es sich hier um ein Programm für User handelt habe ich einstweil die Erstellung des Objektes in einen neuen Thread verschoben und lasse einen Splashscreen anzeigen bis dieser Prozess fertig ist.

Der Konstruktor der Klasse ist in eine 2te Datei ausgelagert aus Übersichtsgründen.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
    public partial class AXLAPIService
    {

        public AXLAPIService(string ccmIp, string user, string password)
        {
            this.Url = "https://" + ccmIp + ":443/axl/";
            this.Credentials = new System.Net.NetworkCredential(user, password);
        }

        public AXLAPIService()
        {
        }
    }


Wie ihr hier sehen könnt macht der Konstruktor (in beiden Varianten) nichts rechentintensives. Es ist wirklich das eigentliche erstellen des Objektes was so eine lange Ladezeit verursacht.


So jetzt zu meiner Frage.
Kann man die Erstellung der Klasse irgendwie Beschleunigen?

Ich hätte dazu momentan nur folgende Idee:
die Klasse in mehrere Klassen aufteilen die Alle von System.Web.Services.Protocols.SoapHttpClientProtocol erben und diese dann jeweils als eigene Objekte in einem eigenen Thread erstellen. Allerdings weiß ich nicht ob das mit dem XMLSerializer und der SOAP API dann noch hin haut.


//edit
Thread Titel überarbeitet
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von Greenberet am So 03.11.13 23:41, insgesamt 2-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 27.10.13 21:36 
Zitat:
Es ist wirklich das eigentliche erstellen des Objektes was so eine lange Ladezeit verursacht.


Woraus schließt du das? Und was soll das eigentliche erstellen des Objekts den deiner Meinung nach sein?
Das nullen des Speichers? Wenn du das glaubst erzeuge mal deine AXLAPIService über FormatterServices.GetUninitializedObject (also ohne di eVErwendung eines Constructors).

Wenn nicht ersichtlich ist woran es liegt solltest du dich eine Profilers bedienen und dann wenn mann das Problem tatsächlich gefunden hat entscheiden was du tust.

Edit: An dem Service hängen tatsächlich eine Menge serialisierbarer Typen. Für die wird beim ersten Start jeweils eine Asssembly erzeugt mit dem Serialiercode.
Den kann man man auch schon statisch erzeugen und einfach referenzieren. Trotzdem würde ich dir raten einen Profiler zu verwenden. Das hier ist nur eine Vermutung.
Greenberet Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: So 27.10.13 22:28 
Hallo Ralph,

ich schätze das Problem liegt in den ganzen Attributen/XMLSerializer der Klasse.

Mein Konstruktor wird auch erst nach einer Minute ausgeführt und nicht gleich am Anfang.

Über FormatterServices.GetUninitializedObject wird das Objekt sofort erstellt.

Laut Profiler braucht er die Zeit im Konstruktor vom System.Web.Services.Protocols.SoapHttpClientProtocol..ctor()


//edit
Der Tip mit dem svcutil führte leider ins Leere =(
Laut svcutil gibt es keine Klassen mit einem ServiceContract
Greenberet Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: So 03.11.13 23:40 
Das Problem ist, dass der XMLSerializer von .NET zur Laufzeit eine DLL erstellt und diese ladet. Bei großen/vielen Klassen kann das natürlich einige Zeit dauern.


Also sollte noch jemand das Problem haben hier die Lösung:
stackoverflow.com/qu...protocol-constructor


  • Man kann diesen Code schon beim kompilieren erstellen "<<PROJECT>>.XMLSerializers.dll" --> es muss nicht zur Laufzeit gemacht werden

    • mit dem Programm sgen.exe (gibt es im .NET SDK)
    • ab VS2012 kann man bei den Projekt Properties unter Build den Punkt "Serialisation" auf ON statt AUTO/OFF stellen.

  • Alle System.Xml.Serialization.XmlIncludeAttribute auf auskommentieren/entfernen
  • [System.Xml.Serialization.XmlSerializerAssemblyAttribute(AssemblyName = "<<PROJECT>>.XmlSerializers")] einmalig vor jeder Klasse angeben die Serialisiert werden soll.
  • Recompile --> fertig =)