Laden...

Forenbeiträge von fungi35 Ingesamt 42 Beiträge

21.09.2021 - 12:04 Uhr

Warum soll sie das nicht? Die Fragestellung zeigt zwei Dinge

  • Wie async/await funktioniert ist unbekannt - es fehlen Grundlagen 🙂
  • Das Konzept soll nicht vollständig angewandt werden, was für die Software-Qualität i.d.R. nicht gesund ist

Wir wollen unsere Software von Background-Workern auf das modernere Task-Konzept umstellen. Aktuell sind es nur Testprojekte. Ich sehe, dass da noch viel Schulungs-/Lern-Bedarf ist.

21.09.2021 - 11:34 Uhr

Ja, das hast Du wohl recht. Es ist nur unschön wenn in internen Schulungen falsche Sachverhalte vermittelt werden.

Rein interessehalber: Wie würde ich SaveAsync() innerhalb einer synchronen Methode richtig aufrufen, wenn ich auf await verzichten muss, da die void-Methode nicht als async markiert werden soll?

21.09.2021 - 11:15 Uhr

Ich bin gerade total verwirrt. Ich hab' mir die entsprechenden Teile der Doku durchgelesen und den Code geändert.
Kannst Du bitte einmal drüber schauen, ob ich es richtig verstanden habe?


        private async Task<SaveResult> SaveAsync()
        {
            return await Task.Run(() =>
            {
                SaveResult retVal = new SaveResult();
                this.dataprovider.save();

                return retVal;
            });
        }


        public async void SaveItem()
        {
            this.ShowWaitingBar();
            SaveResult result = await this.SaveAsync();
            this.HideWaitingBar();
        }

21.09.2021 - 11:01 Uhr

Windows-Forms 🙁

21.09.2021 - 10:49 Uhr

Hallo Leute,

beim Speichern von Daten bekomme ich sporadisch einen Deadlock in der Zeile "SaveResult result = task.Result;".


        private Task<SaveResult> Save()
        {
            return Task.Run(() =>
            {
                SaveResult retVal = new SaveResult();
                this.dataprovider.save();

                return retVal;
            });
        }


        public void SaveItem()
        {
            this.ShowWaitingBar();
            Task<SaveResult> task = this.Save();
            SaveResult result = task.Result;
            this.HideWaitingBar();
        }

Ich möchte auf das Speichern warten, ohne dass die GUI blockiert. In unser letzten c#-Schulung habe ich gelernt, dass das wie oben umgesetzt die beste Methode wäre. Ich verstehe nicht, warum hier ein Deadlock auftritt.

Gruß fungi

13.03.2019 - 09:14 Uhr

Hallo Leute,

ist folgende Konstellation irgendwie umsetzbar?

1.) Windows-Forms-Projekt verweist auf DLLs der Version 402 des Drittanbieters X.
2.) Das DLL-Projekt "Scheduler" verweist auf auf DLLs der Version 705 des Drittanbieters X (die DLLs heißen gleich).
3.) Ein UserControl des DLL-Projekts "Scheduler" soll im Windows-Forms-Projekt verwendet werden.

Kann ich irgendwie dafür sorgen, dass die DLL "Scheduler" immer aus einem separaten Unterverzeichnis gezogen wird, damit es nicht zu Problemen/Konflikten mit den DLLs des Drittanbieters kommt, die sich in der Version aber nicht im Namen unterscheiden?

Vielen Dank!

Gruß fungi

18.09.2018 - 11:03 Uhr

Ich verwende ASP.NET. Was verwendest Du um Zertifikate zu erstellen und zu verwalten?

18.09.2018 - 07:55 Uhr

Hallo Leute,

ich möchte gerne eine RestApi auf https umstellen. Ich habe mir hierfür diesen Artikel sowie einige über google gefundene Lektüre durchgelesen.

Folgende Schritte muss ich jetzt machen:

  • Das [RequireHttps]-Attribut in die Controller implementieren
  • Im IIS eine https-Bindung erstellen
  • Ein Zertifikat beziehen (hierfür habe ich das Tool https://certifytheweb.com/home/download gefunden) und auf dem IIS einrichten

Meine Fragen:

1.) Die RestApi wird von einer Android-App angesprochen, muss auf Client-Seite irgendwas gemacht werden, außer die RestApi mit https://....:Port anzusprechen?
2.) Auf dem Server laufen verschiedene RestApis mit unterschiedlichen Ports, kann ich für jede RestApi dasselbe zertifikat verwenden?
3.) Wie kann ich das Zertifikat mittels certifytheweb oder einem anderen Tool bekommen, ich kann bei dem Domänennamen keinen Port angeben. Keine RestApi läuft auf dem Server auf den Standardports 80/443.

Viele Grüße

fungi

12.02.2018 - 21:08 Uhr

Der Code oben funktioniert (auch) nicht bzw. er bewirkt nicht, dass das Zertifikat akzeptiert wird.

Das CAPI2-Log spuckt folgenden Fehler aus:

Fehlermeldung:

  • System

    • Provider

    [ Name] Microsoft-Windows-CAPI2
    [ Guid] {5bbca4a8-b209-48dc-a8c7-b23d3e5216fb}

    EventID 11

    Version 0

    Level 2

    Task 11

    Opcode 2

    Keywords 0x4000000000000003

    • TimeCreated

    [ SystemTime] 2018-02-12T20:01:26.031218800Z

    EventRecordID 2688

    Correlation

    • Execution

    [ ProcessID] 14476
    [ ThreadID] 16288

    Channel Microsoft-Windows-CAPI2/Operational

    Computer mypc

    • Security

    [ UserID] S-1-5-21-849391721-3056917416-2997542074-1011

  • UserData

    • CertGetCertificateChain

    • Certificate

    [ fileRef] 3681981CCE42123211DFF2B1FCA102B01901BB5A.cer
    [ subjectName] My Company Ltd

    ValidationTime 2018-02-12T20:01:26.031Z

    • AdditionalStore

    • Certificate

    [ fileRef] 3681981CCE42123211DFF2B1FCA102B01901BB5A.cer
    [ subjectName] My Company Ltd

    • ExtendedKeyUsage

    • Usage

    [ oid] 1.3.6.1.5.5.7.3.1
    [ name] Serverauthentifizierung

    • Flags

    [ value] 0

    • ChainEngineInfo

    [ context] user

    • CertificateChain

    [ chainRef] {33CF4FEB-7DDD-4841-9187-DDB12366B2D5}

    • TrustStatus

    • ErrorStatus

    [ value] 20
    [ CERT_TRUST_IS_UNTRUSTED_ROOT] true

    • InfoStatus

    [ value] 100
    [ CERT_TRUST_HAS_PREFERRED_ISSUER] true

    • ChainElement

    • Certificate

    [ fileRef] 3681981CCE42123211DFF2B1FCA102B01901BB5A.cer
    [ subjectName] My Company Ltd

    • SignatureAlgorithm

    [ oid] 1.2.840.113549.1.1.5
    [ hashName] SHA1
    [ publicKeyName] RSA

    • PublicKeyAlgorithm

    [ oid] 1.2.840.113549.1.1.1
    [ publicKeyName] RSA
    [ publicKeyLength] 1024

    • TrustStatus

    • ErrorStatus

    [ value] 20
    [ CERT_TRUST_IS_UNTRUSTED_ROOT] true

    • InfoStatus

    [ value] 10C
    [ CERT_TRUST_HAS_NAME_MATCH_ISSUER] true
    [ CERT_TRUST_IS_SELF_SIGNED] true
    [ CERT_TRUST_HAS_PREFERRED_ISSUER] true

    • ApplicationUsage

    [ any] true

    • IssuanceUsage

    [ any] true

    • EventAuxInfo

    [ ProcessName] xxxxxxxxx.exe

    • CorrelationAuxInfo

    [ TaskId] {D35E6EC8-9382-445D-9FD0-7811CE47DC86}
    [ SeqNumber] 3

    • Result Eine Zertifikatkette wurde zwar verarbeitet, endete jedoch mit einem Stammzertifikat, das beim Vertrauensanbieter nicht als vertrauenswürdig gilt.

    [ value] 800B0109

Ausgestellt wurde das Zertifikat von thawte, deren Rootzertifikate ich gerade alle mal installiert habe (auch ohne Erfolg)

12.02.2018 - 19:55 Uhr

Danke, ich habe das Zertifikat heruntergeladen und auf meinem PC installiert (für meinen lokalen Computer). Komischerweise kommt die Meldung trotzdem noch. Sehr seltsam 🤔

Edit: Die InnerException zeigt die Meldung "Das Remotezertifikat ist laut Validierungsverfahren ungültig." an.

Edit 2: Den Virenscanner (ESET) hab' ich auch komplett ausgeschaltet, der hat auch eine SSL-Prüfung. Bringt leider auch nichts.

12.02.2018 - 19:30 Uhr

Komme ich irgendwie an das Zertifikat oder muss ich dafür den Anbieter kontaktieren?

12.02.2018 - 18:53 Uhr

Hallo Leute,

ich habe die Aufgabe den Webservice (WSDL) eines Fremdanbieters anzusprechen (momentan noch die Test-Version die der Anbieter bereitstellt). Dabei bekomme ich immer die Meldung:

Fehlermeldung:
Die zugrunde liegende Verbindung wurde geschlossen: Für den geschützten SSL/TLS-Kanal konnte keine Vertrauensstellung hergestellt werden.

Daraufhin habe ich das ganze ohne SSL versucht:

            System.Net.ServicePointManager.ServerCertificateValidationCallback +=
            delegate (object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslError)
            {
                bool validationResult = true;
                return validationResult;
            };

Dann geht das System auf die http-Adresse, die es leider aber nicht gibt. Gibt es eine Möglichkeit diesen Fehler zu umgehen?

Gruß fungi35

01.02.2018 - 14:41 Uhr

Hallo Leute,

ich habe eine kurze Frage, auf die ich selber gerade keine Antwort finde:

Ich nutze MVVMLight und das darin enthaltene SimpleIoc für Dependency Injection. Bisher verwende ich ausschließlich Constructor Injection. Ich möchte jetzt auch Property Setter Injection verwenden. Kann es sein, dass das von Haus aus bei MVVMLight nicht unterstützt wird?

Danke & Gruß

fungi

12.10.2017 - 08:26 Uhr

Hallo LaTino,

vielen Dank für die Anmerkung. Ich habe mir den Artikel durchgelesen. So richtig verstanden warum ich das nicht so machen sollte, wie ich es mache habe ich noch nicht. Könnt Ihr mir ggf. bitte nochmal auf die Sprünge helfen?

One way to fix this is to separate the creation and scheduling of the task, e.g.


    Task t = null;
    t = new Task(() =>
    {
        …
        t.ContinueWith(…);
    });
    t.Start();

Das ist doch nichts anderes als mein Code, oder?

            Task<bool> task = new Task<bool>(() => SpeicherZahlungseingaenge(pZahlungseingaenge));
            task.ContinueWith(ZahlungseingaengeGespeichert, TaskScheduler.FromCurrentSynchronizationContext());
            task.Start();
12.10.2017 - 07:32 Uhr

Hallo Sir Rufo,

welchen Vorteil gegenüber meiner Lösung hätte das?

11.10.2017 - 22:38 Uhr

hast Du schon mal in die Doku geschaut?

Jop, als erstes. Allerdings hab' ich es entweder überlesen oder falsch verstanden. Danke für die Aufklärung 😃

11.10.2017 - 21:42 Uhr

Hallo Leute,

ich habe folgendes Konstrukt:


            Task<bool> task = new Task<bool>(() => SpeicherZahlungseingaenge(pZahlungseingaenge));
            task.ContinueWith(ZahlungseingaengeGespeichert, TaskScheduler.FromCurrentSynchronizationContext());
            task.Start();


        private void ZahlungseingaengeGespeichert(object pResult, string pParameter1)
        {

        }

Kann ich der Methode ZahlungseingaengeGespeichert die mittels ContinueWith aufgerufen wird, zusätzlich, neben dem Task.Result, auch einen weiteren Parameter mitgeben? Oder muss ich mir eine entsprechende Klasse für das Task.Result erstellen?

Gruß fungi

23.06.2017 - 08:14 Uhr

Danke LaTino, das werde ich direkt ausprobieren 😃

23.06.2017 - 07:50 Uhr

Ja, das Programm ist im Drei-Schichten-Model umgesetzt. Der Datenbankzugriff ist komplett von der UI getrennt.

Es wäre trotzdem nicht so leicht, das ganze auf Datenbank-Transaktionen umzustellen:

  • Ein Auftrag wird geladen
  • Die Positionen werden geladen (es geht in diesem Thread um die Bearbeitung der Positionen)

Auf DB-Transaktionen umzustellen würde bedeuten, dass beim Starten der Bearbeitung einer Position eine Transaktion gestartet würde, alle Änderungen die an der Position gemacht werden direkt in die Datenbank übernommen werden müssten und die Transaktion anschließend mittels COMMIT oder ROLLBACK beendet werden würde.
Mal angenommen, der Benutzer verwirft seine Änderungen und die Transaktion wird zurückgenommen, dann müsste man auch die Daten der Position aus der Datenbank neu laden, was wiederum auch keinen Geschwindigkeitsvorteil bringen würde. Desweiteren würden wir die Fähigkeit verlieren, das alle Änderungen NICHT übernommen werden, wenn man den gesamten Vorgang (in dem die Positionen enthalten sind) abbricht.

23.06.2017 - 07:20 Uhr

Das ganze auf Datenbank-Transaktionen umzustellen kommt erstmal nicht in Frage, weil der Aufwand dafür viel zu hoch wäre.

22.06.2017 - 23:16 Uhr

Über die Serialisierung wird im Prinzip eine Objekt-Transaktion implementiert.
Beim Starten der Bearbeitung wird das Objekt serialisiert, beim Abbrechen der Bearbeitung wird es wieder deserialisiert und somit in seinen alten Zustand versetzt. Das dauert auch teilweise einen Moment, was ich auch gerne verbessern würde weil es die Usability und den Arbeitsfluss stört.

Ich hatte auch schon darüber nachgedacht, das ganze per Stream direkt in eine Datei zu schreiben und mir so den Weg über den riesigen String im Speicher zu sparen. Da stellte sich mir aber die Frage, ob diese Vorgehensweise die Performance wegen des Festplattenzugriffs nicht verschlechtern würde...

Sonst kannst du dir überlegen ob du nicht in andere Formate serialisiert, die besser für große Datenmengen geeignet sind.
Wenns rein .net ist, so kannst du auch binäre serialisieren.
Sonst schau dir Google Protobuf an.

Google Protobuf sieht sehr interessant aus. Meinst Du, das könnte für meinen oben beschriebenen Anwendungsfall eine gute Anwendung sein?

Welche Vorgehensweise macht generell Sinn, wenn man große Inhalte "zwischenlagern" möchte, ohne das die Anwendung irgendwann einen sehr hohen Speicherverbrauch hat?

22.06.2017 - 20:02 Uhr

Hallo Leute,

ich muss ein sehr großes Objekt (mit vielen enthaltenen Listen und weiteren Objekten) serialisieren und im Programmverlauf wieder deserialisieren (dieser Vorgang wird oft ausgeführt). Momentan wird das Objekt in einen JSON-String (Newton) serialisiert. Es scheint so, bzw. ich habe beobachtet, dass das ganze auf Dauer sehr RAM-intensiv ist.

Ist es so, dass ständiges bilden großer Strings (nichts anderes macht die Serialisierung in diesem Fall ja) viel RAM verbraucht? Kann man die Serialisierung und Deserialisierung großer Objekte auch so gestalten, dass nicht viel RAM für das Serialisieren des Objekts (= bisherige String-Serialisierung) verbraucht wird?

Sorry, wenn ich mich zu kompliziert ausgedrückt habe 😉

Gruß fungi

22.06.2017 - 19:59 Uhr

Danke, ich konnte das Problem mittels Änderung der .config lösen 😃

19.06.2017 - 23:45 Uhr

Hallo Leute,

ich verzweifle gerade an folgendem Problem:

Ich muss den E-Mail-Client Tobit aus unserer Software heraus ansteuern. Das klappt soweit auch und war problemlos umzusetzen. Für die Ansteuerung wird die COM-DLL "DvApi32.DLL" vom Hersteller benötigt. Die DLL wird mit dem E-Mail-Client auf den Rechnern installiert.
Ich habe die DLL ebenfalls auf meinem Rechner (auch registriert) und habe diese über Verweise in unser Projekt eingebunden.

Das eigentliche Problem:

Bei der Ansteuerung des E-Mail-Clients erhalte ich auf dem Kundenrechner folgende Fehlermeldung:

Fehlermeldung:
Die Datei oder Assembly "Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96036d4381770532" oder eine Abhängigkeit davon wurde nicht gefunden. Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)

Die DLL "Interop.DvApi32.dll" liegt im Verzeichnis wo auch die EXE unserer Anwendung liegt. Die Anwendung ist signiert (strong name) und mit Any CPU kompiliert.
Testweise habe ich mal ein Testprojekt mit der Ansteuerung erstellt, welches unsigniert ist. Das Testprojekt läuft auf dem Kundenrechner ohne Schwierigkeiten.

Ich habe auch schon das Logging des Assembly-Binders aktiviert, werde aber nicht schlau daraus. Was mir auffällt ist, dass eine unsignierte Version der DLL im Log aufgeführt wird.

Fehlermeldung:

*** Protokolleintrag für Assembly-Binder (19.06.2017 @ 21:34:16) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80131040. Keine Beschreibung vorhanden.

Der Assemblymanager wurde geladen aus: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt. C:\software\software\Application\vertrieb.exe
--- Ein detailliertes Fehlerprotokoll folgt.

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96036d4381770532
(Fully-specified)
LOG: Appbase = file:///C:/software/software/Application/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = vertrieb.exe
Aufruf von Assembly : (Unknown).
===
LOG: Diese Bindung startet im default-Load-Kontext.
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\software\software\Application\vertrieb.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet:
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96036d4381770532
LOG: Die Suche im GAC war nicht erfolgreich.
LOG: Download von neuem URL file:///C:/software/software/Application/Interop.DvApi32.DLL.
LOG: Download von neuem URL file:///C:/software/software/Application/Interop.DvApi32/Interop.DvApi32.DLL.
LOG: Der Assembly-Download wurde durchgeführt. Datei-Setup wird begonnen: C:\software\software\Application\Interop.DvApi32.dll.
LOG: Die von der Quelle ausgeführte Setup-Phase beginnt.
LOG: Der Assemblyname ist: Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
WRN: Der Vergleich des Assemblynamens führte zum Konflikt: PUBLIC KEY TOKEN.

ERR: Der Assemblyverweis entsprach nicht der gefundenen Assemblydefinition.
ERR: Die von der Quelle ausgeführte Setup-Phase schlug mit hr = 0x80131040 fehl.
ERR: Das Setup der Assembly konnte nicht abgeschlossen werden (hr = 0x80131040). Die Suche wurde beendet.

*** Protokolleintrag für Assembly-Binder (19.06.2017 @ 21:34:16) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80131040. Keine Beschreibung vorhanden.

Der Assemblymanager wurde geladen aus: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt. C:\software\software\Application\vertrieb.exe
--- Ein detailliertes Fehlerprotokoll folgt.

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96036d4381770532
(Fully-specified)
LOG: Appbase = file:///C:/software/software/Application/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = vertrieb.exe
Aufruf von Assembly : (Unknown).
===
LOG: Diese Bindung startet im default-Load-Kontext.
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\software\software\Application\vertrieb.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet:
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96036d4381770532
LOG: Die Suche im GAC war nicht erfolgreich.
LOG: Download von neuem URL file:///C:/software/software/Application/Interop.DvApi32.DLL.
LOG: Download von neuem URL file:///C:/software/software/Application/Interop.DvApi32/Interop.DvApi32.DLL.
LOG: Der Assembly-Download wurde durchgeführt. Datei-Setup wird begonnen: C:\software\software\Application\Interop.DvApi32.dll.
LOG: Die von der Quelle ausgeführte Setup-Phase beginnt.
LOG: Der Assemblyname ist: Interop.DvApi32, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
WRN: Der Vergleich des Assemblynamens führte zum Konflikt: PUBLIC KEY TOKEN.
ERR: Der Assemblyverweis entsprach nicht der gefundenen Assemblydefinition.
ERR: Die von der Quelle ausgeführte Setup-Phase schlug mit hr = 0x80131040 fehl.
ERR: Das Setup der Assembly konnte nicht abgeschlossen werden (hr = 0x80131040). Die Suche wurde beendet.

Gruß fungi

24.05.2017 - 20:02 Uhr

Hallo Leute,

ich habe folgende Frage: Muss ich bei Windows Forms alle Controls auf der Form explizit disposen mittels Dispose()?

Ich habe folgende Dispose-Implementierung in der Form:


        public void Close()
        {
            ((IDisposable)this).Dispose();
        }

        void IDisposable.Dispose()
        {
           this.Dispose(true);
           GC.SuppressFinalize(this);
        }

        ~ViewDruckSelektion()
        {
            this.Dispose(false);
        }

        public void Dispose (bool pDisposing)
        {
            if (pDisposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }

            // Hier die unverwalteten Ressourcen freigeben
            base.Dispose(pDisposing);
        }

Regelt components.Dispose(); den Dispose()-Aufruf für alle in der Form enthaltenen Komponenten?

Gruß fungi

12.05.2017 - 11:27 Uhr

... und warum artikel.GetExportObject() nicht gleich ein ModelExportArtikel liefert.

Weil das Interface nicht generisch ist, das wird gleich noch geändert 😃

12.05.2017 - 11:22 Uhr
 retVal.Artikel = this.Artikel.Select(artikel.GetExportObject() as ModelExportArtikel).ToList();  

Perfekt, danke 😃

12.05.2017 - 10:14 Uhr

Hallo Leute,

gibt es einen Weg diese Codezeilen zu verkürzen:


            foreach (ModelArtikel artikel in this.Artikel)
            {
                retVal.Artikel.Add(artikel.GetExportObject() as ModelExportArtikel);
            }

Gruß fungi

08.05.2017 - 12:24 Uhr

Ich hab's mit Hilfe des SourceCodes der Telerik-Controls herausgefunden. Glücklicherweise steht dieser als zahlender Kunde zum Download zur Verfügung 🙂

07.05.2017 - 11:48 Uhr

Hallo Leute,

ich habe ein Problem, bei dem ich gerade überhaupt nicht weiter komme.

Wir verwenden die Windows Forms-Controls von Telerik in unserem Projekt. Darunter auch das GridView von Telerik. Um auf dem aktuellen Stand zu bleiben haben wir die Version der Telerik-Komponenten von einer zwei Jahre alten Version auf die aktuellste Version aktualisiert.

Leider musste wir feststellen, dass eine Funktion in unserem bestehenden Projekt nicht mehr funktioniert. Unter anderem bietet das GridView von Telerik eine Methode zum Speichern des Layouts (SaveLayout()). Bei allen bestehenden GridViews funktioniert diese Methode nicht mehr, d. h. es wird nur noch eine leere Datei geschrieben.

Das kuriose ist, dass die Methode einwandfrei funktioniert wenn ich:

  • Ein bestehendes GridView woanders hin kopiere (z. B. auf eine andere Form). Auf der neuen Form funktioniert SaveLayout() dann wie gewünscht. Auf der alten Form weiterhin nicht.
  • Ein neues GridView einfüge (egal wo).

Meine eigentliche Frage:

Gibt es evtl. eine Art Cache den ich leeren muss? Projekt bereinigt und neu erstellt habe ich mehrfach gemacht. Auch den bin-Ordner habe ich bereits gelöscht und das Projekt neu erstellt.

Gruß fungi

16.12.2016 - 22:53 Uhr

Hallo Leute,

ich habe eine WebAPI geschrieben und diese per Veröffentlichungs-Funktion (Filesystem) veröffentlicht und auf das neue Live-System (Win 2012 R2) mit dem IIS 8.5 kopiert.
Dann habe ich eine Site im IIS eingerichtet, welche direkt auf das eingefügte Verzeichnis verweist. Gebunden ist das ganze auf Port 4412.

Die Verzeichnisstruktur des Verzeichnisses auf welches verwiesen wird sieht so aus:

  • bin
  • Content
  • fonts
  • Scripts
  • Views
    app.manifest
    Global.asax
    packages.config
    PrecompiledApp.config
    Web.config

Im Bin-Verzeichnis liegt meine Projekt-DLL inkl. der ganzen anderen benötigten DLLs (z .B. Microsoft.Owin.dll).

Das Problem ist, dass die Aufrufe die gegen den IIS auf meinem Entwicklungsrechner laufen funktionieren (sowohl aus einer c#-Anwendung als auch von diversen Android-Geräten), die auf dem neuen Live-System aber nicht.

Wenn ich folgende URL auf meinem Entwicklungssystem aufrufe:

http://localhost:4412/api/TestMethod/

kommt folgende korrekte Ausgabe:

Fehlermeldung:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Message>Authorization has been denied for this request.</Message>
</Error>

Rufe ich die URL auf dem neuen Live-System auf, versucht der Internet-Explorer eine Datei namens "TestMethod/" herunterzuladen, was aber nicht funktioniert.

Die Web.config sieht so aus:


<?xml version="1.0" encoding="UTF-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <!--
    Eine Beschreibung der Änderungen von 'web.config' finden Sie unter 'http://go.microsoft.com/fwlink/?LinkId=235367'.

    Die folgenden Attribute können für das <httpRuntime>-Tag festgelegt werden.
      <system.Web>
        <httpRuntime targetFramework="4.5.1" />
      </system.Web>
  -->
  <system.web>
    <compilation targetFramework="4.5.1" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <handlers>
            <remove name="svc-Integrated-4.0" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
            <add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30AD4FE6B2A6AEED" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Die Logdatei des IIS wirft folgendes aus:

Fehlermeldung:
#Software: Microsoft Internet Information Services 8.5
#Version: 1.0
#Date: 2016-12-16 21:49:27
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2016-12-16 21:49:27 ::1 GET /api/TestMethod/ - 4412 - ::1 Mozilla/5.0+(Windows+NT+6.3;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko - 401 0 0 609
2016-12-16 21:49:27 ::1 GET /api/TestMethod/ - 4412 - ::1 Mozilla/5.0+(Windows+NT+6.3;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko - 401 0 0 0

Könnt Ihr mir evtl. einen Tipp geben der meine Fehlersuche in die richtige Richtung lenkt?

Gruß fungi

18.11.2016 - 10:23 Uhr

Schade, das wollte ich eigentlich zunächst vermeiden. Mir fehlt gerade die Zeit mich auch noch mit der IIS-Konfiguration zu beschäftigen...

18.11.2016 - 08:29 Uhr

Hallo Leute,

ich verweifle gerade etwas. Ich muss über eine Android-App auf eine WebApi-Anwendung zugreifen. Der Zugriff auf die WebApi aus dem Browser und einer c#-Testanwendung heraus direkt vom PC auf dem auch die WebApi (in Visual Studio mit dem IISExpress) läuft (dieser PC hat die IP 192.168.178.107), funktionieren (http://192.168.178.107:4312 als auch http://localhost:4312), über das Netzwerk aber nicht.

Was ich bei google und stackoverflow gefunden habe, habe ich schon ausprobiert, so dass mir die Ideen ausgehen. Die Projekt-URL ist auf http://192.168.178.107:4312/ gestellt.
Ich möchte, dass ich aus dem lokalen Netzwerk http://192.168.178.107:4312 aufrufen kann. Die Windows-Firewall ist ausgeschaltet.

Auszug aus der applicationhost.config:


        <sites>
            <site name="WebSite1" id="1" serverAutoStart="true">
                <application path="/">
                    <virtualDirectory path="/" physicalPath="%IIS_SITES_HOME%\WebSite1" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation=":8080:localhost" />
                </bindings>
            </site>
            <site name="sync_service" id="2">
                <application path="/" applicationPool="Clr4IntegratedAppPool">
                    <virtualDirectory path="/" physicalPath="U:\Working Directory\sync_service\" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:4312:192.168.178.107" />
					<binding protocol="http" bindingInformation="*:4312:localhost" />
                    <binding protocol="https" bindingInformation="*:44367:localhost" />
                </bindings>
            </site>
            <siteDefaults>
                <logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
                <traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
            </siteDefaults>
            <applicationDefaults applicationPool="Clr4IntegratedAppPool" />
            <virtualDirectoryDefaults allowSubDirConfig="true" />
        </sites

Dazu den Befehl


netsh http add urlacl url=http://192.168.178.107:4312/ user=Jeder

ausgeführt.

Entferne ich die Zeilen


<binding protocol="http" bindingInformation="*:4312:localhost" />
<binding protocol="https" bindingInformation="*:44367:localhost" />

kommt eine Fehlermeldung beim Starten des WebApi-Projektes in Visual Studio:

Fehlermeldung:
Der IIS Express-Webserver kann nicht gestartet werden.

Habt Ihr einen Tip was ich noch anders konfigurieren muss, damit ich die WebApi auch von einem anderen Rechner aufrufen kann?

Gruß fungi

09.11.2016 - 16:13 Uhr

Hallo Leute,

ich habe die Aufgabe bekommen einen Web-API-Service zu realisieren (nennt man das so?). Diverse Tutorials habe ich durch und im Browser zeigte mir mein Webservice auch Daten an. Ich möchte anstatt XML JSON verwenden (in- und output).

Bei zwei Problemen, zu denen ich bisher keine Lösung bei google gefunden habe, bräuchte ich Eure Hilfe:

1.) Ich starte das Projekt in Visual Studio, daraufhin öffnet sich der Browser und ich kann mit der entsprechenden URL auch Abfragen machen. Wie bringe ich Visual Studio dazu bei Haltepunkten zu halten, so dass ich die Funktionen debuggen kann? Bisher werden diese überhaupt nicht angesprungen.

2.) Ich habe bei stackoverflow ein Beispiel für eine Authentifizierung gefunden, bekomme es aber nicht zum Laufen und verstehe nicht warum:


[Authorize]
    public class KundenController : ApiController
    {
        private List<Kunde> _Kunden;

        public KundenController()
        {
            this._Kunden = new List<Kunde>();
            this._Kunden.Add(new Kunde { KundenNr = "1", Name1 = "Meier", Name2 = "Metallbau", EMail = "info@meier.de", Ort = "Musterdorf", PLZ = "12345", Strasse = "Musterstrasse 100" });
            this._Kunden.Add(new Kunde { KundenNr = "2", Name1 = "Peter Klaus", Name2 = "", EMail = "info@klaus.de", Ort = "Musterdorf", PLZ = "12345", Strasse = "Musterstrasse 60" });
        }

        // http://localhost:7080/api/kunden
        // GET: api/Kunden
        public IEnumerable<Kunde> Get()
        {
            return this._Kunden;
        }


    public class AuthController : ApiController
    {
        public bool Post(AuthModel model)
        {
            return true;
            if (model.Username == "john" && model.Passwort == "secret")
            {
                FormsAuthentication.SetAuthCookie(model.Username, false);
                return true;
            }

            return false;
        }
    }


    public class AuthModel
    {
        public string Username { get; set; }
        public string Passwort { get; set; }
    }


    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);

            GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
            GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        }
    }

Wenn ich jetzt mit einem Testprogramm die Kunden abfragen machen möchte, dann kommt die Meldung "Response status code does not indicate success: 401 (Unauthorized)."


            try
            {
                using (var httpClient = new HttpClient())
                {
                    string url = "http://localhost:7080/api/auth";
                    var response = httpClient.PostAsJsonAsync(url,
                                    new { Username = "john" Passwort = "secret" },
                                        CancellationToken.None
                    ).Result;
                    response.EnsureSuccessStatusCode();

                    bool success = response.Content.ReadAsAsync<bool>().Result;
                    if (success)
                    {
                        url = "http://localhost:7080/api/kunden";
                        var secret = httpClient.GetStringAsync(url);
                        textBox1.Text = secret.Result;
                    }
                    else
                    {
                        textBox1.Text = "Sorry you provided wrong credentials";
                    }
                }
            }
            catch (Exception ex)
            {
                textBox1.Text = ex.Message;
                
            }

Wenn ich [Authorize] aus der Klasse KundenController entferne kommt die Meldung "> Fehlermeldung:

Response status code does not indicate success: 401 (Unauthorized)." komischerweise immer noch 🤔

Habt Ihr eine Idee was ich falsch mache?

Danke & Gruß

fungi

03.08.2016 - 14:36 Uhr

Ok, neues Beispiel 😃


    public interface ILogonManager
    { 
        string LoggedOnUsername { get; set; }

        bool Login(string pUsername);
        void Logout();
    }//class


    public class LogonManager : ILogonManager
    {
        public string LoggedOnUsername { get; set; }

        /// <summary>
        /// Benutzer einloggen
        /// </summary>
        /// <param name="pUsername"></param>
        /// <returns></returns>
        public bool Login(string pUsername)
        {
            bool retVal = true;
            
            if (!string.IsNullOrEmpty(pUsername))
            {
                this.LoggedOnUsername = pUsername;
            }
            else
            {
                retVal = false;
            }

            return retVal;            
        }

        /// <summary>
        /// Benutzer ausloggen
        /// </summary>
        public void Logout()
        {
            this.LoggedOnUsername = "";
        }
    }//class


    public interface IControllerLogin
    {
        void DoLogin(string pUsername);
    }

    
public class ControllerLogin : IControllerLogin
    {
        private ILogonManager _LogonManager;

        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="pLogonManager">Logonmanager</param>
        public ControllerLogin(ILogonManager pLogonManager)
        {
            this._LogonManager = pLogonManager;
        }

        public void DoLogin(string pUsername)
        {
            this._LogonManager.Login(pUsername);
        }
    }//class


            IUnityContainer container = new UnityContainer();

            container.RegisterType<ILogonManager, LogonManager>();
            ILogonManager logonmanager = container.Resolve<ILogonManager>();

            container.RegisterType<IControllerLogin, ControllerLogin>(new InjectionConstructor(logonmanager));
            IControllerLogin controller = container.Resolve<IControllerLogin>();
            controller.DoLogin("Peter");

So injecte ich den Parameter des Konstruktors, richtig?

Wie handhabt man es, wenn ich innerhalb der Klasse ControllerLogin Instanzen anderer Klassen erstelle, die wiederum auch Zugriff auf den LogonManager haben sollen. Nutze ich da auch DI oder kann ich die Instanzen normal erstellen mit:


xxx = new(this._LogonManager) 

Wie weit treibt man es mit der DI bzw. wie weit ist es sinnvoll sie zu verwenden?

03.08.2016 - 13:24 Uhr

Ich hab' noch nie damit gearbeitet (bin noch Azubi), würde die Thematik aber gerne lernen.

Bei Unity sieht die Arbeit ungefähr so aus:

  • Über NuGet Unity installieren
  • UnityContainer-Property anlegen (Eine Zeile)
  • Beim Start der Anwendung das Objekt registrieren (eine Zeile)
  • Dort, wo es gebraucht wird, abrufen (Eine Zeile)
    Der Aufwand ist mittlerweile sehr gering, der Langzeit-Nutzen aber hoch.

Ist der Code so richtig umgesetzt?


IUnityContainer container = new UnityContainer();
container.RegisterInstance<IUser>("UserLoggedOn", new LoggedOnUser());

UnityServiceLocator loc = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => loc);

Abfragen der Instanz dann irgendwo wo es benötigt wird mit:


IUser user = ServiceLocator.Current.GetInstance<IUser>("UserLoggedOn");

05.06.2016 - 13:36 Uhr

Hallo Leute,

ich schreibe gerade ein Outlook-Addin welches osTicket mit Tickets versorgt. Hierzu habe ich auf github das Projekt "OsTicket.API-master" gefunden (ein c#-Wrapper für die osTicket-API).

Die Übertragung der E-Mails ins Ticketsystem funktioniert auch schon recht gut, nur die Umlaute wollen noch nicht: Aus ß wird Ã, aus ö wird ö, usw.

Ich habe schon versucht das Encoding dem JSON-Serializer sowie dem RestClient zu übergeben, beides brachte bisher keinen Erfolg:


            RestClient client = new RestClient(OsTicketUrl) { Encoding = Encoding.UTF8 };

            IRestRequest request = new RestRequest("/api/tickets.json", Method.POST);
            request.JsonSerializer = new RestSharp.Serializers.NetwonsoftJsonSerializer();
            request.JsonSerializer.ContentType = "application/json; charset=utf-8";
            request.AddHeader("X-API-KEY", ApiKey);
            request.RequestFormat = DataFormat.Json;

            TicketDTO ticketDTO = TicketDTO.CreateFromTicket(ticket);
            JObject jo = JObject.FromObject(ticketDTO);
            foreach (KeyValuePair<string, object> pair in ticket.ExtraFields)
            {
                jo.Add(pair.Key, JToken.FromObject(pair.Value));
            }

            request.AddBody(jo);

            IRestResponse response = client.Execute(request);

            if (response.StatusCode == HttpStatusCode.Created)
            {
                return int.Parse(response.Content);
            }
            else
            {
                throw new Exception(response.Content);
            }

Habt Ihr einen Tipp für mich was ich noch falsch mache/vergessen habe?

Gruß fungi

10.10.2015 - 15:11 Uhr

Hi Leute,

ich habe die Aufgabe in einem größeren Projekt das Standard-TabControl durch ein TabControl eines Drittanbieters zu ersetzen.

Ich habe mir überlegt, in wie weit ich das durch Suchen und Ersetzen erledigen kann. In der .designer.cs sollte das relativ gut funktionieren.

Muss ich noch etwas außer die designer.cs beachten? Gibt es serialisierte Werte die Visual Studio speichert?

Gruß fungi

30.09.2015 - 20:02 Uhr

Hallo Leute,

ich habe eine Anwendung auf einem Win2012-Terminalserver auf den sich die User direkt per RDP aufschalten. Der Server befindet sich im Internet. Die Druckerumleitung ist aktiv, d. h. die lokalen Drucker stehen auch auf dem Terminalserver zur Verfügung.

In einer Druckauswahlmaske zeigen wir alle vorhandenen Drucker inkl. der jew. vorhandenen Schächte an.

Die Drucker und Schächte werden durchlaufen und separat gecached. Das Durchlaufen der Druckerinformationen dauert teilweise, abhängig von der Internetverbindung bis zu 10 Minuten, was natürlich alles andere als benutzerfreundlich ist.


for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
{
	PrinterSettings settings = new PrinterSettings();
	settings.PrinterName = PrinterSettings.InstalledPrinters[i];

	............

	foreach (PaperSource source in settings.PaperSources)
        {
	.............
	}
}

Auf dem gleichen Server ist auch Microsoft Word installiert, dort gibt es überhaupt keine Verzögerungen. Man merkt quasi gar nicht, dass die Drucker über eine RDP-Verbindung via Internet angesprochen werden.

Habt Ihr eine Idee wie Word das bewerkstelligt?

Danke & Gruß

fungi35

27.03.2015 - 00:00 Uhr

Hallo Leute,

vielen Dank für die vielen hilfreichen Antwort. Ich bin der Ursache schon ein Stück näher gekommen. Mittels des Memory Profilers habe ich herausgefunden, dass die Generation 2 Collection immer weiter anwächst. Ich komme leider nur sehr langsam voran, weil ich keinerlei Erfahrungen mit Memory Profilern habe und die Objektstruktur sehr komplex ist.

26.03.2015 - 08:46 Uhr

Hallo Abt und MrSparkle,

danke für Eure Antworten 😃
Zugegebenermaßen habe ich es nur im Taskmanager geprüft und nicht mit dem ProcessExplorer.

Das Problem ist, dass die Anwendung sehr sehr langsam wird, sobald der Speicherverbrauch (laut Taskmanager) auf eine bestimmte Größe (bei meinem Tests trat das Problem ab ca. 1,8 GB auf) angewachsen ist. Starte ich die Anwendung neu und führe genau dieselben Aktionen durch, ist die Anwendung sehr performant (Aktionen dauern 1 Sekunde) - aber halt nur bis zu einem gewissen Zeitpunkt (dann dauern dieselben Aktionen 1 Minute).

Ich habe mich auch schon gefragt ob die Restore-Methode richtig umgesetzt ist. Reicht es aus eine Liste mit .Clear() oder = null zu leeren? Werden dabei auch die Referenzen der Child-Objekte der Liste gelöscht? Dazu finde ich bei google, insbesondere bei stackoverflow, unterschiedlichste Aussagen.
Die Positionsobjekte aus der Liste enthalten weitere Listen die an mehrere GridViews gebunden werden. Muss ich diese Listen noch explizit mit .Clear() leeren? Die DataSource der GridViews wird beim Abbrechen der Bearbeitung immer mit GridView.DataSource = new BindingList<...>() überschrieben, so dass eigentlich keine Referenz mehr vorhanden sein dürfte.

Kannst Du mir einen MemoryProfiler empfehlen?

fungi35

25.03.2015 - 20:52 Uhr

Hallo Leute,

ich bin recht neu in c# und habe ein Anwendung eines Kollegen übernommen.
Ich habe eine Frage zur Speicherverwaltung und bräuchte mal einen Hinweis mit ich in die richtige Richtung komme.

In der Anwendung gibt es eine Positionsbearbeitung mit einem Grid. An das Grid ist eine generische Liste mit den Positionsobjekten gebunden. Wird eine Position bearbeitet wird die entsprechende Position inkl. gesamter Objektstruktur in eine separate Liste (ich nenne sie mal Backup-Liste) kopiert (Deep Copy mittels ICloneable). Eine Position hat ggf. auch zugehörige Unterpositionen die im Laufe der Bearbeitung mit verändert werden, deshalb wohl die Backup-Liste. Die Objektstruktur ist sehr umfangreich, das Clonen aber noch performant.

Wird die Position abgebrochen, werden die Daten aus der Backup-Liste wieder zurück in die originale Liste geschrieben:


        public void RestorePositionen(IList<Model_VorgangPosition> pBackup,
                                      IList<Model_VorgangPosition> pZiel)
        {
            foreach (Model_VorgangPosition position in pBackup)
            {
                Model_VorgangPosition positionzuersetzen = this.Positionen.Where(o => o.Pos.Equals(position.Pos) &&
                                                                                 o.UPos.Equals(position.UPos)).Single();
                int index = this.Positionen.IndexOf(positionzuersetzen);
                this.Positionen[index] = position;
            }
        }

pZiel ist die Liste die an das Grid gebunden ist. pBackup ist die Backup-Liste.
Nach der Übernahme der Daten aus der Backup-Liste wird die Backup-Liste geleert (beim Speichern der Position wird das .Clear())ebenfalls aufgerufen):


this._OldPositionen.Clear();

Mein Problem ist, dass der Speicherverbrauch sehr schnell sehr groß wird (2 GB sind keine Seltenheit), je öfter man Positionen bearbeitet. Dadurch wird die ganze Anwendung insbesondere das Clonen bei einem erneuten Bearbeiten einer Position extrem langsam (anfangs dauert das Clonen 1 Sekunde, später 1 Minute, obwohl sich die Daten gar nicht verändert haben).

Was muss ich alles prüfen um sicherzustellen, dass der Speicher wieder freigegeben wird?
Wie lösche ich Objektreferenzen sicher, so dass die Objekte auch aufgeräumt werden? Mir ist klar, dass der Speicher nicht zwangsläufig und unmittelbar vom GC wieder freigegeben wird, aber diesen hohen und unnötigen Speicherverbrauch würde ich gerne abstellen.
Gibt es einen Unterschied zwischen set objekt = new abc() und set obj = null?

Könnt Ihr mir einen Hinweis in die richtige Richtung geben? Gerne auch, wie man diese ganze Backup-Listen-Geschicht besser lösen kann.

Vielen Dank

Gruß fungi35