Laden...

Forenbeiträge von Arti Ingesamt 9 Beiträge

02.02.2023 - 19:48 Uhr

Hallo,

ich habe 3 Klassen (aufgeteilt in 3 cs-Files):

FHC_Main.cs


class FHC_Main
    {
        static void Main(string[] args)
        {
            CommandLineCheck commandLineCheck = new CommandLineCheck();
            commandLineCheck.DoCommandLineCheck();

            Logger logger = new Logger();
            logger.log();
        }
    }

CommandLineCheck.cs


internal class CommandLineCheck
    {
        public static string log;
        public void DoCommandLineCheck() 
        {
                log = @"D:\Entwicklung\temp\logfile.txt";
        }
    }

Logger.cs


internal class Logger
    {
        public void log()
        {
                System.IO.StreamWriter LogToFile = new System.IO.StreamWriter(CommandLineCheck.log, append: true);
                LogToFile.WriteLine("TEST");
                LogToFile.Close();
        }
    }

Ich habe also in der Klasse "CommandLineCheck" die Variable "log" als public static string definiert und kann dann aus der Klasse "Logger" darauf zugreifen (CommandLineCheck.log).
Das funktioniert einwandfrei...

Ich frage mich aber, ob "man das so macht" oder ob es da keine elegantere Methode gibt...
Ich brauche den Inhalt von "log" in der Logger-Klasse, evtl. aber auch in anderen Klassen.
Ich hätte gerne "log" als globale Variable...

Ist das was ich hier tue der richtige Weg oder kann man das eleganter machen?

Danke euch!
Arti

07.01.2023 - 15:12 Uhr

Ok, danke Dir.
Das werde ich mir morgen mal anschauen!

07.01.2023 - 14:32 Uhr

Hallo Abt,

danke für Deine Antwort.

Das Problem beim Erklären des Themas ist, das ich in Unity etwas scripte und nicht "nur" einfach ein C#-Programm schreiben will...

Aber: DU HAST MIR GEHOLFEN!

Mit den Stichwort "Field" bin ich weiter gekommen:

ZugriffKlasse.cs


using System;
using System.Diagnostics;
using System.Reflection;

public class ZugriffKlasse
{
	public void LeseAndereKlasse()
	{
        Program p = new Program();
        Console.WriteLine("Klasse gestartet...");

        foreach (FieldInfo fieldInEDb in typeof(Program).GetFields())
        {
            Console.WriteLine(fieldInEDb.Name);
            Console.WriteLine(fieldInEDb.FieldType);

        }
    }
}

Das tut genau das was ich will...
Name gibt des Namen des Fields zurück, FieldType den Typ...

Also DANKE für Deine Hilfe!
Grüße,
Arti

07.01.2023 - 13:38 Uhr

Hallo liebe C#-Profis,

ich habe als Anfänger ein Problem bei dem ich trotz intensiver Google und Forumssuche keine Lösug finde - wahrscheinlich weil ich nicht weiß wie das was ich tun will genau "heißt".

Program.cs


using System;

public class Program
{
    public string strFromKlasse;
    public int intFromKlasse;
    public float floatFromKlasse;

    static void Main(string[] args)
    {
        ZugriffKlasse zK = new ZugriffKlasse();

        Console.WriteLine("Programm gestartet...");
        zK.LeseAndereKlasse();
    }
}

ZugriffKlasse.cs


using System;

public class ZugriffKlasse
{
	public void LeseAndereKlasse()
	{
        Program p = new Program();
        Console.WriteLine("Klasse gestartet...");

        // Hier möchte ich eine Ausgabe aller public-Variablen in der Klasse Programm
        // Das sind folgende:
        // string strFromKlasse;
        // int intFromKlasse;
        // float floatFromKlasse;
        // ----------------------
        // Ich möchte folgende Daten: Datentyp und Name der Variable
        // Console.WriteLine("Type: " + Variablentyp.ToString() + " Name: " + Variablenname.ToString());
        // Variablentyp.ToString() & Variablenname.ToString() sind natürlich von mir erfunden! Ich weiß leider nicht wie ich diese Informationen bekomme...
    }
}

Wie im Text steht, möchte ich von der ZugriffKlasse-Klasse auf die Program-Klasse zugreifen und erfahren welche Public Variablen denn dort eigentlich definiert wurden.
Ich möchte wissen wie der Typ der Variable ist (zB string, int, float) und die die Variable heißt (zB strFromKlasse, intFromKlasse, floatFromKlasse).

Ich weiß nicht ob das überhaupt geht bzw. wenn es geht, wie...

Kann mir jemand helfen?

Wäre super nett!
Vielen Dank!
Arti

23.11.2022 - 16:51 Uhr

Wenn ich


a = hashline.Hash;

sind beide Maschinen in einer Sekunde durch...🙂

Ich denke es ist ein Zusammenspiel zwischen CPU/Speicher/IO - ich denke die langsameren PCs sind einfach deutlich Leistungsschwacher als mein i9

Hat bestimmt auch was mit dem Speicherzugriff zu tun - der scheint bei den Servern viel langsamer zu sein...

23.11.2022 - 16:15 Uhr

Ich poste mal einen Demo-Code der so komplett ist:


using System.IO;

namespace Speed
{
    class Program
    {

        public static List<CListe> Liste = new List<CListe>();

        static void Main(string[] args)
        {
            Console.WriteLine("Start: " + DateTime.Now);
            for (int i = 0; i < 100000; i++)
            {
                Liste.Add(new CListe() { Hash = i.ToString(), Path = "c:\\Temp\\Test\\Word.exe" });

            }
            Console.WriteLine("Befüllt: " + DateTime.Now);

            string a = "";
            foreach (CListe Hashline in Liste)
            {
                a = a + Hashline.Path;
            }

            Console.WriteLine("Fertig: " + DateTime.Now);
        }
        public class CListe
        {
            public string Hash { get; set; }

            public string Path { get; set; }

            public override string ToString()
            {
                return "Hash: " + Hash + " Path: " + Path;
            }
        }
    }
}

Der Teil


            foreach (CListe Hashline in Liste)
            {
                a=a+Hashline.Hash;
            }

dauert auf dem i9-11900K 50 Sekunden
Auf dem Xeon 180 Sekunden - also 3,x mal so lange.

Vielleicht liegt es wirklich nur an der CPU-Performance...

PS: Oben hab ich geschrieben das die Performance auch langsamer ist wenn die Schleife leer ist... Das stimmt nicht.
Mache ich in der foreach-Schleife nichts, sind beide Maschinen in einer Sekunde durch!

23.11.2022 - 15:37 Uhr

Die Struktur der Liste ist wie folgt:


public class md5list
        {
            public string Hash { get; set; }

            public string Path { get; set; }

            public override string ToString()
            {
                return "Hash: " + Hash + " Path: " + Path;
            }
        }

Dh die Liste hat einmal einen 32-Stelligen MD5-Hash und dazu ein dazugehören Pfad/dateiname

Beispiel:
1234567890abcdef1234567890abcdef c:\test\word.exe
Hash + Path

Wenn ich diese Liste mit


foreach (md5list Hashline in intersectList)
            {
                // HIER PASSIERT GARNIX!!!
            }

durchgehe, geht das auf dem i9-11900K in einer Minute, auf dem Xeon W-2265 dauert es 20 minuten.

Um zu testen wird in der foreach-Schleife wirklich garnix gemacht!

Das was auf dem Xeon so langsam ist, ist einfach das Durchgehen durch die Liste mit foreach.

Und irgendwie kann ich mir nicht vorstellen das der Xeon soooooooo langsam ist... die CPU läuft gerade mal auf 15%, einer der Kerne vielleicht auf 60%...
Ich habe das nun auch einem Xeon W2265 und mehrern VMs (alle haben Server-Prozessoren) getestet...
Ergebnis: Server-CPU = ultra-lahm
i9-Desktop = schnell

Gibt es evtl. Compiler-Einstellungen die evtl falsch gesetzt sein könnten?

23.11.2022 - 12:28 Uhr

Ich habe mein Performance-Problem eingrenzen können:


foreach (md5list Hashline in intersectList)
            {
                //..
            }

Der Durchlauf dauert auf meinem i9-11900K nur eine Minute (hier entwickel ich).
Auf einem Xenon W-2265 dauert das 20 Minuten...

Ich kann mir vorstellen das der Xenon X-2265 langsamer ist, aber so extrem, ich verstehe es nicht.

Jemand eine Idee?

23.11.2022 - 09:11 Uhr

Hallo,

ich habe ein c# Consolenprogramm (.Net6) geschrieben mit dem ich 2 Listen vergleiche:

Ich bin kein Profi oder ähnliches, ich habe mir das alles per Try-Error beigebracht... also bitte nicht so streng sein...


// Step 1: Create a union list from the first and the second (only single entries. Duplicates will be removed automatically)
var unionList = md5lines1.Union(md5lines2, new DoCompare());
// Step 2: Create a list with the entries, which are in both lists 
var intersectList = md5lines1.Intersect(md5lines2, new DoCompare());
// Step 3: Get the entries which only in the union list and not in the intersect list
var exceptList = unionList.Except(intersectList);
// Step 4: Create a list with entries only in file1
var onlyFile1 = exceptList.Except(md5lines2);
// Step 4: Create a list with entries only in file2
var onlyFile2 = exceptList.Except(md5lines1);

Die Listen sind zum Teil sehr groß und haben mehrere Millionen Einträge.

Beim Ausführen fällt mir nun auf, das nur einer meiner 16 CPU-Cores benutzt wird.
Im Taskmanager sehe ich, das alle Cores auf 1-5% rumdümpeln, nur einer läuft auf 100%.

Um das ganze zu beschleunigen möchte ich, das die Software alle Cores nutzt, damit das alles schneller geht...

Ich war der Meinung das das automatisch von Windows gemanaged wird, scheint aber nicht so zu sein...

Kann mir jemand sagen wo/wie ich das ganze "Multicore-Fähig" machen kann, bzw. wie aufwändig das ist?!?

Danke euch!