Laden...
Avatar #avatar-2894.jpg
gfoidl myCSharp.de - Team
Entwickler in der Gasmotorenbranche (nicht nur Software) Waidring Dabei seit 07.06.2009 6.912 Beiträge
Benutzerbeschreibung
FIS-Speedski (S-DH) world champion 2015 3x FIS-Speedski (S-DH) overall worldcup winner, 2008/09, 2009/10, 2012/13 5x Subaru Velocity Challenge winner, 2009, 2010, 2013, 2014, 2015 7x PopKL Verbier winner, 2009 2x, 2010 2x, 2011 2x, 2013 1x 27 victories in 69 international Speedski-races v_max = 208,333 km/h http://de.wikipedia.org/wiki/Günther_Foidl

Forenbeiträge von gfoidl Ingesamt 6.912 Beiträge

20.05.2024 - 19:21 Uhr

Hallo Patsche,

schau dir in diesem Zusammenhang auch Span an.

mfG Gü

21.03.2024 - 10:30 Uhr

Hallo Ralf2022,

_should_stop sollte auch volatile sein bzw. via Volatile.Write/Read geschrieben/gelesen werden. Siehe Doku warum (dort ist auch ein Beispiel dabei).

Den TcpListener, etc. würde ich auch erst nach dem (erfolgreichen) Stopp schließen (bzw. Dispose aufrufen). So wird das sofort durchgeführt und das kann ev. zu anderen Fehlern führen.

Weiters schau dir Tasks an, da sich damit wesentliche effizienter Clients handhaben lassen, als wenn je ein neuer Thread erstellt wird (das hat sehr viel Overhead).

mfG Gü

13.03.2024 - 17:14 Uhr

Hallo Palladin007,

das gRPC-Tooling erstellt eine partielle Klasse, da kann das interface einfach angehängt werden nachdem VS die Definition extrahiert hat.

Die InProcess-Implementierung ist trivial zu coden.

Wenn ich davon ausgehe dass Änderungen an der proto-Datei selten sind, ist der Aufwand dafür viel geringer als eine robuste InProcess-Channel-Implementierung zu erstellen.

z.B. DI-Scope muss verwaltet werden

?

Wenn so in etwas für DI so registiert wird

services.AddScoped<ITestClient>(sp =>
{
    if (inProcess /* via Konfiguration, etc. ermittelt */)
    {
        return new InProcessTestClient();
    }

    return // IPC
});

Nach meiner Erfahrung wird eben eine proto eher selten geändert, insofern hast du viel Aufwand für diese Implementierung bei wenig Nutzen.

Interface und InProcess Code könnte auch per Source-Generator erstellt werden, aber da gilt das Gleiche: viel Aufwand für ...
Daher würd eich diese einfach händisch coden -- aus Kosten/Nutzen-Sicht.


Ein weiterer Vorteil vom IClient-Interface ist, dass es bei Tests einfacher ist dieses zu Mocken. Die gRPC-Calls können zwar auch gemockt werden (z.B. der Unary-Call), aber das ist wiederum mehr Aufwand.

mfG Gü

13.03.2024 - 12:23 Uhr

Hallo Palladin007,

wenn du den TestService.TestServiceClient durch ein ITestServiceClient wegabstrahierst und das verwendest, so kann per DI je nach Konfiguration eine Instanz mit Netzwerkkommunikation od. ohne (also direktem Aufruf) durchgeführt werden.
Da ersparst du dir das Erstellen eines Invokers für die In-Process Variante.

mfG Gü

12.03.2024 - 14:17 Uhr

Hallo JuergenG,

Best-Praxis

Ideal wäre wenn die Formel als Objekt-Modell vorliegt, da du somit allerhand machen kannst:

  • Werte berechnen
  • rendern als LaTeX für PDF, PNG, etc.
  • rendern als MathJax für direkt Anzeige in einer Website
  • rendern als irgendwas (z.B. Baum)

Du hast somit so gut wie alle Möglichkeiten. Klar ist das ein wenig Aufwand...

Fürs Parsen der Formel und Überführen in ein Objekt-Modell kannst du ev. einen vorhanden Parser (wie Th69s Parser für mathematische Formeln) verwenden od. du inspierierst dich an vorhanden Lösungen (wie ein altes Demo-Projekt von mir).

Hashtable

Du meinst Dictionary<K, V>? Die HashTable ist untypsisiert und sollte nicht mehr verwendet werden.


Kleine Anmerkung zu

Es geht tatsächlich, wie gezeigt, um diese

Wo wurde "gezeigt"? Bis zu diesem Punkt hätte das (in deinem Sinne) abgekürzt werden können, wenn diese relevanten Infos gleich in der 1. Frage aufgetaucht wären. Bisher wurde das nicht gezeigt und bisher war das Ziel auch nicht klar -- zumindest mir nicht, dass es dir klar ist, davon gehe ich einmal aus.

mfG Gü

12.03.2024 - 11:24 Uhr

Hallo Palladin007,

jetzt weiß ich gar nicht mehr was du willst 😉

es wird nichts serialisiert

gRPC nutzt Protobuf zur Serialisierung. Auch wenn es durch gRPC wegabstrahiert wurde, gibt es dennoch die Serialisierung -- anders könnten die Objekte ja nicht übermittelt werden.

... hinter der generierten Abstraktion. Das Protokoll dahinter gibt es also gar nicht mehr

So sollte eigentlich jede IPC / Kommunikation aussehen. Die tatsächliche Übertragung der Daten sollte nur ein Implementierungsdetail sein, das nicht direkt angesprochen wird.
Z.B. können die vom gRPC-Tooling erstellten Services auch ohne gRPC aufgerufen werden.

nur ein Quasi-Ersatz für die gRPC-Kommunikation

Das meinte ich im vorigen Kommentar. Ist es IPC dann kann der gRPC-Client verwendet werden, ist es In-Process kann der Service direkt* aufgerufen werden -- je nach Konfiguration.
Dazu ist aber keine "Channel-Implementierung" (aus deiner Frage) nötig und die würde das nur komplizierter als nötig machen.

* mit direkt meine ich hier schon via einer Schnittstelle, da sich über diese eben per Strategie-Muster das schön abstrahieren lässt

Aber es geht ja gerade um die Projekte, wo man beides haben möchte, abhängig von der Konfiguration.

Und bei dem Punkt verstehe ich nicht warum das per Strategie nicht einfacher gehen sollte?
Hast du noch andere Anforderungen die mir zum Bild deines Anliegens fehlen?

mfG Gü

12.03.2024 - 11:11 Uhr

Hallo JuergenG,

ganz verstehe ich dein Problem noch immer nicht.

Wenns darum geht feste Formeln wie

\begin{align*} 
  100 \mathrm{mm^2} \cdot \frac{\pi}{4} &= 0.785 \mathrm{cm^2} \\
  \sqrt{\left( 100 \frac{\mathrm{N}}{\mathrm{mm^2}} \right)^2 + 3 \cdot \left(15 \frac{\mathrm{N}}{\mathrm{mm^2}} \right )^2} &= 103.32 \frac{\mathrm{N}}{\mathrm{mm^2}}
\end{align*}

mit variablen Werte zu befüllen, so kann einfach String-Interpolation benutzt werden. Dann mit einem LaTeX Compiler das PS, PDF, PNG, etc. erstellt werden. Dies dann in ein DOCX od. PDF einzubinden ist ein anderes Thema (aber eigentlich auch nicht schwer, v.a. hier könnte das PDF gleich mit LaTeX erstellt werden).

Es gibt auch Web-Dienste denen LaTeX übergeben wird und die ein PNG, etc. rendern können, so dass u.U. der Ablauf vereinfachen kann. Z.B. wie die Formel von oben.

mfG Gü

11.03.2024 - 11:18 Uhr

Hallo JuergenG,

was ist jetzt deine Frage?
Gehts um LaTeX generell, einen in C# geschriebenen Parser für LaTeX od. um das Rendering von LaTeX Ausdrücken?

mfG Gü

11.03.2024 - 11:16 Uhr

Hallo Palladin007,

In-Process gRPC ist nur unnötiger Overhead (auch wenn Sockets od. Named Pipes als Transport verwendet werden).
Da würde ich eher die Abstraktion so ziehen, dass entweder der Kommunikations-Layer (gRPC) verwendet wird od. alles In-Process läuft (Methoden-Aufrufe).

Die via proto-Files generierten Typen können in beiden Fällen verwendet werden.
Die Methoden-Aufrufe gehen alle gegen ein interface und je nach Konfiguration ist die konkrete Ausprägung dann ein Typ der In-Process arbeitet od. ein Typ der via gRPC mit dem Server kommuniziert.

Kurz gesagt: wenns rein In-Process ist, so überspringe den gRPC-Kommunikationsteil einfach und ruf die Server-Methoden direkt auf.

mfG Gü

27.02.2024 - 22:10 Uhr

Hallo Loofsy,

kannst du ein bischen spezifischer werden als nur "3D Drucker"?
Es gibt ja ein paar mögliche Datei-Formate dazu.

Weiters wäre dann auch gut zu wissen wie du mit dem 3D Drucker kommunizieren willst bzw. was dieser zur Kommunikation unterstützt.

mfG Gü

12.12.2023 - 09:45 Uhr

Hallo aloneboy,

vorab: für den rechtlichen Aspket, sprich ob das erlaubt ist od. nicht, bist du verantwortlich.

Schau dir Playwright od. Puppeteer an.

mfG Gü

06.12.2023 - 10:07 Uhr

Hallo Palladin007,

braucht man Reset(), was ich persönlich bisher noch nicht hatte.

I.d.R. braucht man das auch nicht.
Aber wenns der Iterator gecached werden soll, so lässt sich per Reset der Zustand zurücksetzen bevor in den Cache kommt. Das ist aber schon eher ein Sondefall...(hab das selbst auch erst einmal so verbaut)

mfG Gü

20.11.2023 - 10:50 Uhr

Hallo JayDee72,

setzt doch einfach mal die Umgebungsvariable ASPNETCORE_ENVIRONMENT=Development und schau dir den Fehler an.

Greift die App auf eine Datenbank zu? Passen dort die Zugriffsrechte?
Dateizugriffsrechte, usw. Das sind die üblichen verdächtigen.

Außerdem teil uns doch mit wohin und wie die App veröffentlicht wird. Raten können wir schon, aber obs zielführen ist...

mfG Gü

Edit: race condition mit Abt, er hat gewonnen 😃

15.11.2023 - 09:40 Uhr

Hallo,

gut dass es jetzt wenigsten passt und Danke dass das hier gepostet wurde.

VS ist manchmal wirklich eigenartig...die Reihenfolge der Projekte sollte eigentlich egal sein, da ja "nur" eine In-Memory Repräsentation aufgebaut wird.

Solltest du dennoch (irgendwann) weitere Ursachen für das Problem eruieren können, so wäre es super wenn auch diese Ergebnise hier präsentiert werden können.

mfG Gü

14.11.2023 - 18:29 Uhr

Hallo Michael Hößel,

ich tippe dass irgendeine Erweiterung / Extension das Problem ist.
Versuch mal VS ohne Erweiterungen zu starten.

mfG Gü

03.11.2023 - 10:33 Uhr

Hallo pollito,

noch ein kleiner Tipp: die Condition in MsBuild (die *.csproj ist im Grunde eine Projekt-Datei für MsBuild) kann vereinfacht werden:

 <PropertyGroup Condition="'$(Configuration)'=='Debug'">
   <DebugType>full</DebugType>
 </PropertyGroup>
 <PropertyGroup Condition="'$(Configuration)'=='Release'">
   <DebugType>none</DebugType>
 </PropertyGroup>

Hier könnte auch z.B. für Debug die Condition ganz wegfallen, d.h. es wird zuerst der Wert für alle Konfigurationen gesetzt (es kann ja auch mehr als Debug und Release geben), dann für Release wird er überschrieben.

mfG Gü

02.11.2023 - 19:28 Uhr

Hallo pollito,

dann lösch die App.config einfach (wenn eh nichts drin ist).

mfG Gü

13.10.2023 - 12:00 Uhr

Hallo Th69,

da die Konsumentenseite wesentlich vereinfacht wird und dort keine expliziten Callbacks / Handler nötig sind.

mfG Gü

13.10.2023 - 11:03 Uhr

Hallo AceTecNic,

warum verwendest du jetzt den BackgroundWorker wenn doch oben ein Beispiel für Tasks gegeben ist.
Noch dazu wäre es dann besser wenn die Logik für die Druckkraft komplett von der UI entkoppelt wird und dann sollte der BGW nicht mehr bekannt sein. Außerdem kann die Task-Variante per Unit-Tests leicht(er) geprüft / validiert werden als mit dem BGW. Dieser macht vor knapp 20 Jahren sinn als es Tasks noch nicht gab.

mfG Gü

11.10.2023 - 23:22 Uhr

Hallo cprogrammer,

der Sinn eines Forums ist es bestimmt nicht leicht zugängliche, leicht findbare Dokumentation zu ersetzen.
Hättest du nur ein wenig die Grundlagen von C# und .NET erlernt, und dabei sprechen wir nicht von Jahren, sondern Stunden, Tage, etc. so erübrigen sich diese Fragen.

Bedenke auch dass hier im Forum alle freiwillig dabei sind. Daher ist es fast schon ein wenig unverschämt die Last etwas zu recherchieren auf die Community umzuwälzen.
Dein Umgangston bzgl. T-Virus finde ich hier nicht OK, denn immerhin hat er sich die Mühe gemacht und für dich ein paar Links rausgesucht.

Alleine die Frage "nach dem mergen von C# und C++ DLL" zeigt, dass das Konzept von .NET mit der managed Runtime noch nicht angekommen ist. Das wird übrigens in der .NET Doku recht am Anfang schon erörtert...

mfG Gü

09.10.2023 - 16:23 Uhr

Hallo AceTecNic,

mit einem Ereignis (event) "zerreißt" du den Codefluss.
Eine andere Möglichkeit, v.a. wenn eh ein separater Thread verwendet werden soll ist die Verwendung von Tasks und hier besonders unter Zuhilfenahme einer TaskCompletionSource.

Ganz grob skizziert so:

const int MaxSecondsToWaitForCondition = 100;
Func<bool> conditionToCheck = () =>
{
    Thread.Sleep(500);
    return true;
};

// irgendein Code

using CancellationTokenSource cts = new(TimeSpan.FromSeconds(MaxSecondsToWaitForCondition));
Task waitForConditionTask = WaitForConditionAsync(conditionToCheck, cancellationToken: cts.Token);

// anderer Code

await waitForConditionTask;

static Task WaitForConditionAsync(Func<bool> condition, int pollDelayMillis = 100, CancellationToken cancellationToken = default)
{
    TaskCompletionSource tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);

    Task.Run(async () =>
    {
        try
        {
            while (!condition())
            {
                await Task.Delay(pollDelayMillis, cancellationToken).ConfigureAwait(false);
            }

            tcs.SetResult();
        }
        catch (OperationCanceledException ex)
        {
            tcs.SetCanceled(ex.CancellationToken);
        }
    }, cancellationToken);

    return tcs.Task;
}

mfG Gü

24.09.2023 - 10:46 Uhr

Hallo Sandmann,

if(Assembly.GetAssembly(typeof(T)) is Assembly assembly)

Hier hast du Patterrn Matching für die null-Prüfung elegant gelöst bzw. sinnvoll kombiniert.

Allerdings könnte das auch so geschrieben werden:

Assembly assembly = typeof(T).Assembly;

das spart den null-Check.

mfG Gü

13.09.2023 - 22:19 Uhr

Hallo cprogrammer,

was scheinbar bullet proof ist.

Ist es nicht.
Sobald der Code ausgeführt wird, lässt sich das mit einem Debugger rekonstruieren. "Bullet proof" geht hier nicht, aber das solltest du über die Forensuche, etc. schon gefunden haben 😉

wäre zu Lehrzwecken schon recht interessant ?

Ein gut gemeinter Rat: zu Lehrzwecken wären die Grundlagen von C# / .NET interessanter als irgendwelche komischen Dinge die eh nicht funktionieren.

mfG Gü

13.09.2023 - 12:00 Uhr

Hallo sbsbsbsb,

wenn die Kommunikation später auch über einen Server im Internet laufen könnte

Da hast du zwei eher gegensätzliche Anforderungen:

  • einmal etwas Peer-to-Peer-artiges
  • einmal (Zitat) eine Client-Server-Architektur

Ich würde mich gleich für letzteres entscheiden (unter der Annahme dass die Anzahl der Clients nicht sehr groß sein wird), da so auf dem Server z.B. SignalR laufen kann (ASP.NET Core). Die Clients sind dann flexibler, denn existiert für viele Plattformen entsprechende Client-Libraries.

Alternativ kann auch gRPC mit Streaming verwendet werden, dort existieren für noch mehr Plattformen die Libraries.
Mit gRPC wäre auch das Peer-to-Peer artige Szenario möglich.
Allerdings sind hier Sachen wie Broadcasts etwas schwieriger umszusetzen als bei SignalR.

Möglich wäre auch etwas eigenes basierend auf UDP zu erstellen, sofern die Nachteile von UPD (bitte selbst recherchieren) nicht gravierend sind.

Eine Instanz mach einen Server auf

Hört sich erstmal recht einfach an, aber zuverlässige Leader Election ist nicht so trivial wie es klingt.
Das ist mit ein Grund warum ich Cleint-Server-Architektur bevorzugen würde.

mfG Gü

29.08.2023 - 14:00 Uhr

Hallo rockxk,

Die Anwendung benötigt die vcredist_x86.exe Runtime als Vorraussetzung.

Dann wissen wir einmal dass es eine 32-bit native Windows Anwendung auf Basis der C++ Runtime ist.
Wenn du die C++/CLI Variante probierst, achte daher auf 32-bit Einstellung.
Ich vermute der Weg via NativeAOT wird hier hingegen nicht klappen, da der Office-Teil eher nicht dazu bereit ist. Sonfern also ein Test wie von Th69 vorgeschlagen klappt, so wäre das der mögliche Weg: C# / .NET Logik -> Kapselung per C++/CLI -> Einbindung ins Skript der Hauptanwendung.

mfG Gü

29.08.2023 - 10:33 Uhr

Hallo rockxk,

die DLL erfolgreich als Visual Studio Projekt per Reverse E. erstellen können

ist das lizenzrechtlich hier gestattet?

wird die DLL dynamisch (per Linker) angesprochen

Genau, daher heißt es ja "dynamic link library". Allerdings erledigt dieses dynamische Linken nicht ein Benutzerprogramm, sondern das Betriebssystem in Form der "Loader"-Komponente.

Mir ist die ganze Architektur hier noch unklar und du beantwortest leider die Fragen nicht. Ebenso ist es sehr hilfreich wenn du nicht beurteilen kannst ob X od. Y -- wie sollen hier hilfreiche Kommentare produziert werden?

  • Ist die Hauptanwendung nativ od. managed -- also C/C++ od. C#?
  • Was soll die zu ersetzende DLL genau ansprechen? Neueres Outlook...nunja das kann auch wieder Vieles sein. Falls dort wiederum Inline-Assembler nötig ist, so geht das mit C# / .NET nicht. Ist Inline-Assembler nicht nötig, so geht das womöglich (siehe Kommentare oben).

Ein Upgrade der Hauptsoftware ist aus Kostengründen (>100.000€) nicht möglich und nach heutigem Stand auch nicht mehr sinnvoll.
Ein Ersatz ebenfalls nicht, da eine ganze Produktion daran hängt.

Da habt ihr aber eine sehr weitsichtige Führungsetage. Das ist schon fast grob fahrlässig -- leider aber auch sehr oft anzutreffen.
Wir hier ernsthaft daran geglaubt, dass das System, an welchem die ganze Produktion hängt, durch Reverse Engineering, Rumbasteln an einer DLL, etc. in die Zukunft gehebelt wird?

mfG Gü

28.08.2023 - 19:12 Uhr

Hallo rockxk,

gehts um .NET Framework od. um .NET (Core)?
Je nachdem gibt es verschiedene Möglichkeiten, denn bei neuen Versionen von .NET kann via NativeAOT eine DLL erstellt werden, welche ein C-ABI hat ("DllExport") und dadurch könnte neben der genannten Möglichkeit mit C++/CLI auch die DLL erstellt werden.

Beim gezeigten nativen Code wird mit Inline-Assembler direkt gearbeitet, daher bedenke dass dies mit C# / .NET nicht möglich ist. Vllt. bist du besser dran wenn diese Teile in C++ bleiben? (Kann ich natürlich so nicht für dich beantworten).

Im Hauptprogramm werden diese externen Funktionen angesprochen bzw. eingebunden.

Per [DllImport] od. durch Laden der DLL?

Diese DLL soll durch eine neue ersetzt werden, wobei das Hauptprogramm, welches die DLL lädt nicht "angefasst" bzw. verändert werden kann.

Also wenn die DLL durch eine managed Komponente (C# DLL) ersetzt werden soll, so wäre es naheliegend auch im Hauptprogramm das direkt od. via "Assembly Load" anzusprechen, statt einen Umweg managed → native → managed zu gehen.
Wenn du diese Einschränkung also irgendwie ändern kannst...

mfG Gü

09.08.2023 - 19:35 Uhr

Hallo,

es wird wohl auch Änderungen in Roslyn und NuGet geben (müssen):

  • Roslyn wird einen Analyzer nur dann ausführen, falls kein externes IO außer AdditionalFiles ausgeführt wird
  • NuGet (-Server) wird beim Indizieren der Pakete auch den Code prüfen müssen und eventuell das Paket ablehnen

Das Unding von kzu wird wohl noch größere Kreise ziehen.
Schade dass der OSS-Gedanke hier so mockig behandelt wurde.

mfG Gü

07.08.2023 - 11:25 Uhr

Hallo cprogrammer ,

Ich vermisse hier

  • etwas Eigeninitiave
  • Beschäftigung mit den Grundlagen, die leicht der Doku, etc. zu entnehmen sind

Tu dir doch den Gefallen und lies dich ein. Das kostet auch viel weniger Zeit als in einem Forum solche Fragen zu stellen und auf eine Antwort zu warten.

mfG Gü

04.08.2023 - 16:08 Uhr

Hallo Palladin007,

so pauschal kann ich das nicht sagen, denn es hängt auch von der konkreten Anwendung* ab. Dort nehm ich dann halt das "natürlichste" wie sich das aufteilen lässt. Klar jetzt kommt die Frage: "was ist das natürlichste?" und ich würd die Antwort gleich beginnen wie diese 😉

* also jetzt nicht nur WPF mit MVVM od. sonst was, sondern obs Benutzerverwaltung, Simulationsprogramm, etc. ist

Ich würde auf jeden Fall Commands und Queries separarieren (das muss nicht unbedingt in CQ(R)S ausarten und kann auch in MVVM verwendet werden), dann hab ich schon einmal (grob) eine Aufteilung nach Use Cases.
Das Ganze dann in Verbindung mit der jeweiligen View ergibt eien Art "Feature" und dieses ist in einen eigenen Ornder / Namespace gepackt. Dort ist dann alles drin, was für dieses Feature benötigt wird und erspart die lästigen Sprünge quer durch die Solution, so ist es leichter zu verstehen da zusammengehördende Dinge auch nah beinander liegen. Größere Projekte lassen sich so auch recht elegant umsetzen, ohne dass alles irgendwie fragil erscheint und sich keiner mehr auskennt.

mfG Gü

04.08.2023 - 11:30 Uhr

Hallo teebeast,

Darf auch gerne allgemein gehalten sein

grundsätzlich ist zwischen Anwendungsentwicklung und Library-/Framework-Entwicklung zu unterscheiden, da beide Gruppen verschiedene Ziele verfolgen. Hier gehts um die Anwendungsentwicklung und da halte ich es "nicht so abstrahiert wie möglich, sondern so abstrahiert wie nötig", wobei sich das nötig mehr od. weniger von alleine ergibt um testbaren Code zu haben.

Muster (Pattern) stellen Ideale dar, welche sich im Laufe der Zeit herauskristallisiert haben. Das heißt jedoch nicht automatisch, dass jedes Muster gem. Referenzimplementierung voll und ganz umgesetzt werden soll/muss. Es sollte eher als Anleitung, grober Bauplan, Orientierung gesehen werden. Daher wenn für euer Team das funktioniert, der Code testbar ist wozu mehr Aufwand für weitere Abstraktionen betreiben?

Uns fehlen hier auch gewisse Konstrollstrukturen wie Softwarearchitekten oder Code Reviews

Das lässt sich ja ändern. V.a. mit Code Reviews kann jederzeit und leicht begonnen werden. Alleine schon durch Fragen wie "warum wurde das so gelöst" kann innerhalb des Teams eine interessante Diskussion entstehen, bei deren Ende alle der Diskussion teilhabenden mehr Verständnis für die Lösung haben, die u.U. letztlich ganz anders aussehen kann.
Code Reviews sind nicht nur Kontrolle, sondern auch Lernen und Verstehen.

Der UI-Bereich besteht nun aus mindestens vier Assemblies

Ist das nicht eine künstliche Einschränkung dass es "mind. vier Assemblies" sind? Das führt ja zwangsläufig zu

merke aber dass ich erhebliche Probleme habe, mich im Quellcode zu orientieren.

und den weiters angeführten Problemen. Zudem hat das großes Fehlerpotential, da auf einem Blick die Zusammehänge wohl kaum überschaubar sind.
Probier mal -- z.B. in einem Test-Projekt -- die "Bestandteile" von MVVM näher zusammenzurücken, z.B. in einem Unterordner im Projekt. Dann ist die Orientierung im Code leicht, das Verständnis was der Code tut ebenfalls leicht überschaubar. Änderungen und Weiterentwicklungen gehen dann zügiger voran, da eben das Verständnis vorhanden ist und nur in einem Ordner gewert werden braucht, anstatt in 2, 3, 4 Assemblies wo fast niemand genau weiß warum dort.

Sollte dann z.B. das Model woanders auch benötigt werden, also falls sich dieser Fall tatsächlich ergibt, so kann das ja verschoben werden.
Aber von vornhinein würde ich (heute) keine Projekte mehr zwangsmäßig in (thematische) Assemblies aufteilen (XYZ.View, XYZ.ViewModel, XYZ.Models, etc.), sondern das nach Anwendungsfällen (use cases), Benutzeraktionen, usw. aufteilen.

mfG Gü

29.07.2023 - 10:54 Uhr

Hallo,

Zeigeroperationen fallen unter "unsafe code"

Und das zu recht, denn C# (zusammen mit .NET als Runtime) garantiert die sichere Ausführung vom Code, d.h. es gibt keinen Buffer-Überlauf, keine Zugriffsverletzungen durch Lesen/Schreiben außerhalb vom zulässigen Speicherbereich (wie Arrays), usw.
Es wird z.B. eine IndexOutOfRangeException erzeugt falls der Index nicht innerhalb des gültigen Bereichs ist, anstatt eine "Access Violation" zu erzeugen od. überhaupt den falschen Speicherbereich zu lesen, welches auch ein Sicherheitsrisiko darstellt.

Außer es wird explizit "unsafe code" aktiviert, so ist für die Code-Bereiche, welche per unsafe markiert wurden, der Programmierer selbst in der Verantwortung das Richtige zu tun ("allows to shoot oneself in the foot").

BTW: im modernen .NET gibt es die Unsafe und MemoryMarshal Klassen, welche eigentlich auch als "unsafe code" gelten, nur momentan keinen entsprechenden Compiler-Switch benötigen. Dazu gibt es aber einen Vorschlag dies zu ändern (welchen ich unterstütze).

Ist bei C# das Thema "Zeiger" überhaupt noch ein Thema oder muss man sich darum gar nicht mehr kümmern ?

Zeiger sind in C#

  • für Anwendungsentwicklung so gut wie nie nötig -- außer es wird per Interop mit nativem Code zusammengearbeitet
  • für low-level Bibliotheks-Code (z.B. String-Handling) teilweise nötig um Tricks, welcher C# so nicht zulassen würde, zu verwenden damit auf diesen unteren Schichten des Runtime-Stacks optimale Performance vorhanden sein kann

Da der Großteil der Programmiertätigkeit wohl eher in den Bereich der Anwendungsentwicklung fällt, Zeiger in C# ein fortgeschrittenes Thema sind, rate ich dir diese erstmal zu vergessen. Du wirst mit C# / .NET Bordmitteln das Ausreichen haben (sofern die Grundlagen und Konzepte von .NET sowie C# verstanden wurden).

mfG Gü

13.07.2023 - 10:56 Uhr

Hallo JayDee72,

Ich möchte z.B. mit dem ermittelten Namen auf das AD zugreifen....

Kannst du beschreiben was du damit genauer machen willst?
Oft ist ein direkter AD-Zugriff nicht nötig, sondern die relevante Infos können anders ermittelt werden.

Außerdem ist das eine Blazor-App (?), da würde ich so od. so nicht direkt aufs AD zugreifen wollen (zwecks Sicherheit). Besser wäre da den AD-Zugriff via Backend-API zu erledigen.

mfG Gü

06.07.2023 - 17:00 Uhr

Hallo Micha21tts,

noch als kleiner Hinweis da es um Distanzvergleiche geht: die Wurzelfunktion ist streng monoton, daher gilt sqrt(x) < sqrt(y) => x < y. D.h. es ist nicht nötig die Wurzel zu berechnen, da diese aufwändig ist. Z.B. im Projekt, das T-Virus verlinkt hat, braucht es hier keine Wurzel, es genügt mit dem quadratischen Abstand weiter zu rechnen.

Abgesehen davon und sollte es zu Lern-/Übungszwecken dienen, so würde ich versuchen den Algorithmus zu verstehen und dann selbst umzusetzten. Falls du dann dabei irgendwo hängst, so können wir weiterhelfen, nicht jedoch als allgemeiner Codelieferant 😉

mfG Gü

28.06.2023 - 10:43 Uhr

Hallo Kriz,

schau dir dazu Configuration an und dazu auch Environment.

Damit bleibt der Code "schön" (ohne die Präprozessor-Direktiven) und jeweiligen Einstellungen (ConnStrings, etc.) können in Abhängigkeit von der Umgebung (Environment) geladen werden.
So ist auch lokales Testen, Testen in CI, Staging, Produktion, etc. einfach und ohne Änderung im Code möglich.

mfG Gü

22.06.2023 - 11:55 Uhr

Hallo,

der Sharplab Link suggeriert dass beide Varianten zu gleichem Code kompiliert werden. Tatsächlich wird der C#-Code vom Compiler zu IL kompiliert und dort sind die Unterschiede (Variante A / B) zu sehen.
Für den C#-Reiter in Sharplab wird zwar gleicher Code angezeigt, da Sharplab intern das IL zu C# zurückführt (und hier wohl eine semantisch korrekte Repräsentation zeigt, jedoch keine 1:1 Repräsentation).

BTW: Lowering hat mit dieser "Umwandlung" nichts zu tun -- lowering wäre z.B. foreach über Array → for-Schleife usw.

Gibt es hier ein BestPractice?

Sehe ich wie T-Virus. Argument-Validation zu Beginn der Methode und dann entweder entsprechende Fehler schmeißen od. aus Methode aussteigen.

Hat eine der Versionen Performance-Vorteile?

Ist das relevant?
Und falls ja, so spätestens mit .NET 8 nicht mehr, denn dort ist die sogenannte dynamische profilgestützte Optimierung (D-PGO) des JIT aktiviert und dadurch erzeugt der JIT Maschinencode in Abhängigkeit vom tätsächlichen Programm-Ablauf.
Hier im Beispiel (egal ob Variante A od. B) falls x nie od. zumindest selten (< 50 %) null ist, so wird der Block für "null-Fall" in den "kalten" Bereich der Method geschoben. Kurz: die Performance ist in beiden Fällen gleich.

Wie die Frage nach der "Relevanz" schon angedeutet hat, würde ich mir darüber keine Gedanken machen und v.a. den Code leserlich schreiben.
Sollte Profiling, etc. zeigen dass diese Methode kritisch ist, dann (und "nur dann") ist es sinnvoll diese zu optimieren. Ein paar Tricks gibt es dazu.

Wobei ab .NET 7 Leserlichkeit und Perf Hand in Hand gehen bei ein paar Exceptions.
Vor .NET 7:

public int Foo(object x)
{
    if (x is null)
    {
        throw new ArgumentNullException(nameof(x));
    }
    
    return x.GetHashCode();
}

Ab .NET 7:

public int Foo(object x)
{
    ArgumentNullException.ThrowIfNull(x);
    
    return x.GetHashCode();
}

Der Code wird IMO leserlicher und es zugleich weniger Maschinencode vom JIT erzeugt.

Anmerkung: im Beispiel ist das Argumnet object x und nicht object? x (also mit nullable annotations). Da Foo eine public Methode ist und x eben nicht als null erwartet wird (daher keine Annotation) muss auch das Argument validiert werden -- sprich ein Fehler erzeugt werden, falls es doch null ist.
Anders ist es bei folgendem Beispiel:

public int Bar(object? x)
{
    return x is not null
         ? x.GetHashCode
         : 0;    // od. welcher Wert auch immer für `x is null` verwendet werden soll
}

Hier wird null erlaubt, daher muss null auch toliert werden und ein Ergebnis ohne Fehler (Exception) zurückgegeben werden.

Insofern kann ich

keine Null-Checks mehr, außer ich markiere den Parameter als nullable, dann zwingt (wenn ich es als Fehler behandeln lasse) der Compiler mich dazu.

nicht richtig einordnen. Vllt. ist es richtig gemeint od. auch nicht. Jedenfalls so wie ich es beschrieben haben ist es im Sinne von Nullable-Annotations.

Im private oder internal Code schreibe ich persönlich gar keine Null-Checks mehr

Das hat eigentlich noch nie wirklich Sinn gemacht (also Null-Checks in nicht öffentlichen Methoden), da diese ja nur von public Methoden aufgerufen werden können (direkt od. indirekt). Um dennoch potentielle NullReferenceException vorzubeugen kann man

/* internal od. */ private int Foo(object x)
{
    Debug.Assert(x is not null);
    
    return x.GetHashCode();
}

schreiben. Dann wird zumindest beim Debuggen od. falls CI/CD mit einem Debug-Build die Tests auch durchführt dieses Assert ausgeführt. Im Release-Build wird dieses Assert vom C#-Compiler weggelassen, daher auch keine negativen Effekte für die Perf.

mfG Gü

16.06.2023 - 10:48 Uhr

Hallo cprogrammer,

ergänzend zu Abts Antwort uns falls es wirklich ums statische "Linken" gehen soll, dann siehe Native AOT.

Neben deiner anderen Frage, stellt sich mir jedoch die Frage "wozu das Ganze"?
Steckst du gedanklich in C/C++ fest und hast den Sprung zu managed Sprachen / Runtimes wie C# und .NET noch nicht vollzogen?

mfG Gü

02.06.2023 - 20:51 Uhr

Hallo Christoph K.,

Gibts es hierzu schon irgendetwas vorgefertigtes?

Schau dir dazu einmal Roslyn Analyzers an. Damit kann direkt per API vom Compiler gearbeitet werden und somit der (geparste) Syntaxbaum auch verändert werden (via Fixer). Das ist dafür gedacht -- ich vermute mit Regex wirst du viel mehr falsch positive Treffer erhalten.

mfG Gü

30.04.2023 - 12:38 Uhr

Hallo Christoph K.,

Dies geht ja nun nicht mehr, und mann muss alle Parameter in einer Klasse kapseln und dann in Form eines Parameters + dem Attribute [FromBody] in die Parameterliste schreiben.

Schau dir dazu Binding source parameter inference an.

mfG Gü

30.04.2023 - 12:11 Uhr

Hallo pollito,

ich verwende Code alignment
Und dank der Shortcuts, die konfigurierbar sind, geht das ruckzuck.

mfG Gü

18.04.2023 - 20:52 Uhr

Hallo,

vor lauter Klammern und vielleicht | Verknüpfungen ein ! untergehen sieht

Hängt natürlich vom konkreten Fall ab, aber das könnte auch in eine lokale Funktion (ab C# 7) ausgelagert werden, dann ist es übersichtlich und u.U. das ! auch nicht mehr nötig.

mfG Gü

18.04.2023 - 14:02 Uhr

Hallo,

bei einem bool finde ich if (bedingung == true) / if (bedingung == false) unsinnig, da eben durch das bool dies schon eindeutig ist. Den Punkt bzgl. Lesbarkeit, v.a. bei Personen mit Sehschwäche, lass ich gelten, aber hier sollte m.E. eine Extension im Editor das optisch besser darstellen als unnötigen Code zu schreiben.

Anders bei bool? / Nullable<bool>. Um nicht mit Konstrukten wie GetValueOrDefault(false), ?? false, etc. hantieren zu müssen, kann das ein if (nullableCondition is true) durchauch hilfreich sein.
Das is true würde ich aber nicht bei if (nonNullableCondition) verwenden, alleine um dort schon den Unterschied zwischen bool und bool? deutlicher parat zu haben.

Lesbarkeit als sehr wichtig

Stimmt, v.a. da Code i.d.R. öfter gelesen als geschrieben wird.
Für mich ist jedoch == false nicht lesbarer, es stört vielmehr. Daher lässt sich auch über den Punkt Lesbarkeit diskutieren.

mfG Gü

18.04.2023 - 09:56 Uhr

Hallo Caveman,

die vorgestellte Lösung funktioniert, jedoch sollte bei Algorithmen auch die Aufwandsklasse berücksichtigt werden. Hier ist diese recht hoch. Bei kleinen Mengen mag das kein Problem darstellen, aber es gibt effizientere Lösungen wie jene von BlonderHans od. via HashSet.

mfG Gü

17.04.2023 - 21:59 Uhr

Hallo 4noxx,

am einfachsten und mit .NET-Klassen geht via HashSet. Schau dir diesen Typ einmal an und du siehst die zur Verfügung gestellten Mengenoperationen.

Wenn du es jedoch -- zu Lernzwecken -- lieber händisch durchprogrammieren willst, so ist ein naiver Ansatz einfach für jedes Element der einen Liste in der Zielliste zu Suchen ob es dort vorhanden ist od. nicht. Entweder (ganz) naiv per verschachtelten Schleifen od. etwas besser über die Array.Find-Methode.

Probiers einmal aus, falls du hängst helfen wir gerne weiter.

mfG Gü

06.04.2023 - 11:56 Uhr

Hallo sv00010kas,

falls in deinem Browser noch so ist, kannst du bitte einen Screenshot anhängen?
Wäre interessant wie das aussieht.

mfG Gü

30.03.2023 - 11:07 Uhr

Hallo Sandmann,

super, das ist auch viel effizienter als mein Versuch. Im Bild unten deine Variante.

mfG Gü

29.03.2023 - 16:37 Uhr

Hallo ThomasE. ,

angenommen die Tabelle heißt Foo, dann z.B. mittels Common Table Expression und Cross Apply:


with cte as
(
    select  f.Id, f.Nr
    from    Foo f
    group by f.Id, f.Nr
)
select  t.*
from    cte c
cross apply (
    select  top 1 *
    from    Foo f
    where   f.Id = c.Id
        and f.Nr = c.Nr
    order by f.IsSet desc
) t

Geht vermutlich effizienter...

mfG Gü

16.03.2023 - 14:16 Uhr

Hallo zusammen,

ab C# 7 kann mittels Pattern Matching der Code auch als


if (bedingung is true)
{
    // ...
}

// Oder

if (bedingung is false)
{
    // ...
}

mfG Gü

01.03.2023 - 13:15 Uhr

Hallo P.St. ,

das Projekt auf .Net Framework 4.8.1 migriert

Warum nicht .NET 6 (LTS) od. .NET 7 (STS)?
Da wird Arm auch besser unterstützt als bei .NET Framework 4.8.1. Wenn schon migriert wird, so schau dir doch die neueste Version von .NET (aktuell 7, .NET 8 gibts als Preview) an. Zusätzlich bietet der JIT und die Libraries dort mehr Optimierungen für Arm an, so dass zusätzlich der Code effizienter abgearbeitet wird.

mfG Gü

25.02.2023 - 10:53 Uhr

Hallo T-Virus,

Bei ARM beziehe ich mich mehr auf die Sparsamkeit im Leerlauf als auf die Performance.

Dann schreib das doch gleich 😉
Bisher war die Argumentation nicht sehr schlüssig, eher lose Aussagen.

Mir gehts nicht um die eine od. andere Seite (x86 od. Arm), da ich je nach Anwendungsfalls die ein od. andere Technologie passender halte, sondern darum dass die getätigten Aussagen auch entsprechend arguemntiert werden (das gilt nicht nur für dich).

Bei dem Umweltthema muss man halt auch beachten, dass die Hardware zum ersetzen auch erstmal gebaut werden muss.

Da stimme ich zu.
Vom eigentlichen Thema "Transition von x86 auf Arm" rutschen wir schon ein wenig ab, aber in "Smalltalk" ist das nicht so streng...
Beim Umweltthema könnte auch schon viel getan werden, wenn viel unnötiges Streaming, Social-Media stark reduziert werden würde. Da geht es oft nur um "Müll" den eh keinem interessiert, aber TB an Daten produziert werden.

Auch wenn ich jetzt selbst vom Thema abgewichen bin und die Tür für eine weitere Diskussion geöffnet habe, sollten wir versuchen beim Haupt-Thema Arm <-> x86 zu bleiben.

mfG Gü