Laden...
Avatar #avatar-2894.jpg
gfoidl myCSharp.de - Team
Entwickler in der Gasmotorenbranche (nicht nur Software) Waidring Dabei seit 07.06.2009 6.911 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.911 Beiträge

16.03.2018 - 15:49 Uhr

Hallo Krumnix,

wenn du es "perfekt" machen willst, dann geht das via Transpiler -- so wie es pinki auch vorgeschlagen hat.

Falls der Aufbau des Programms gleich ist und nur die Syntax andere Schlüsselwörter verwendet, so kann ein Suchen & Ersetzen (ev. mittels Regex.Replace und MatchEvaluator) auch reichen. Das ist weniger aufwändig als obiger Vorschlag.

Prüfe aber auf jeden Fall ob die Funktionsumfänge zwischen beiden µC gleich sind, sonst wird kaum ein anderer Weg als manuelles Übersetzen bleiben.

mfG Gü

14.03.2018 - 12:30 Uhr

Hallo schuppsl,

genau, einfach eine WebAPI welche als "Proxy" mit SAP kommuniziert.
Mehr als die Aufrufe entgegebennehmen, "übersetzen" für SAP und die SAP-Kommunikation macht die nicht.

Je nach Anforderung / Netzwerk / etc. kann noch Authentifizierung dabei sein.

mfG Gü

13.03.2018 - 19:02 Uhr

Hallo schuppsl,

ich stand einmal vor einem ähnlichen Dilemma mit SAP-x64 und .net Core. Wenn ich mich richtig erinnere scheiterte es auch daran, dass die SAP-DLL mit managed C++ erstellt wurde und das wird -- zumindest war es damals so -- von .net Core nicht unterstützt.

Meine Lösung war dann ein .net-Full API welche mit SAP kommuniziert.
Die asp.net Core API kommunizierte dann mit der .net-Full API.
Das beste aus beiden Welten 😉

mfG Gü

13.03.2018 - 14:35 Uhr

Hallo schuppsl,

für SAP gibt es auch x64-Dlls.

Siehe auch .NET Core x86 Console App Crashes

mfG Gü

09.03.2018 - 17:53 Uhr

Hallo Caveman,

ergänzend zu Abts Antwort, kannst du mit Shared Project das Problem mit der Versionierung nicht lösen.

Schau dir NuGet einmal ein, mach ein Demo / Prototypen und spiel damit herum. Dann wirst du merken, dass es schon passt 😉

mfG Gü

07.03.2018 - 19:17 Uhr

Hallo Caveman,

schau dir NuGet an. So kannst du gezielt eine Version einer Referenz einbinden.

Lokale Feeds kannst du ebenso nutzen wie myget, etc.

mfG Gü

07.03.2018 - 10:06 Uhr

Hallo ZeroQool,

der Freiberufler soll ein Anbot machen und wenn der Preis passt, so wird gekauft, nachverhandelt, etc.

Die Entwicklungskosten sind nur ein Kriterium für den Preis. Es spielt da noch viel mehr mit:* Nutzungsrechte -- Exklusivität

  • ev. Produktwartungen
  • Dokumentation und Support
  • etc.

Genauso wie es eine Individualsoftware ist, so wird es auch eine individuelle Lösung für den Kauf geben (müssen).

mfG Gü

06.03.2018 - 10:35 Uhr

Hallo Thron,

wenn schon Threads dann via ThreadPool und vorzugsweise "angesteuert" per Tasks.

Wie schon erwähnt wurde, ist der Overhead für die Ausführung in einem (ThreadPool-) Thread sicherlich höher als der reine Abgleich.
Ohne die genaueren Anforderungen und deine Anwendung zu kennen, wäre Pipelines, Producer/Consumer (cf. SyncQueue <T> - Eine praktische Job-Queue) möglich. Sollte die Anwendung WinForms od. WPF sein, so ist ein Producer / Consuer bereits in der Nachrichtenschleife eingebaut -> [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)
All diese Möglichkeiten können zur asynchronen Abarbeitung verwendet werden.

mfG Gü

22.02.2018 - 10:10 Uhr

Hallo Wax,

hast du Debug-Infos (pdb-Dateien) generiert und von dort stammen die Pfade bzw. Bezüge zur Zeilennummer?

mfG Gü

18.02.2018 - 19:29 Uhr

Hallo RuMaGuM,

der dazu passende GoF-Pattern ist Chain-of-responsibility pattern, der durch Abts Snippets elegant abgebildet wurde. Wobei die Variante mit dem Dictionary nicht zuverlässig ist, denn

Zitat von: Dictionary<TKey
The order in which the items are returned is undefined.

Somit könnte es zu falschen Ergebnissen kommen -- zumindest kann sich auch das Framework ändern und die Reihenfolge ist nicht mehr deterministisch, das wäre auch keine Breaking Change, denn so ist es auch dokumentiert. Mit einem OrderedDictionary, etc. bei dem der Key auch für die Sortierung verwendet werden kann, lässt sich dieser Punkt aber eliminieren.

mfG Gü

18.02.2018 - 19:21 Uhr

Hallo Gerri3d,

Gibt es eine empfehlenswerte Möglichkeit, Spracherkennung zu verwenden?

In Form einer fertigen Library (siehe Abts Antwort) od. in Form von Algorithmen die selbst umgesetzt werden sollen?

Für letzteres sollte "etwas" auf Basis von Markov-Ketten reichen. So wurde bis vor Kurzem Sprachsteuerung umgesetzt. Wobei "etwas" jetzt schon sehr abstrakt geschrieben ist, aber als Orientierungsstichwort für weitere Recherchen ist das ein Ausgangspunkt.

mfG Gü

11.02.2018 - 18:55 Uhr

Hallo lhyn,

dass das Forum kein Pattern-Generator ist, hast du vllt. noch nicht mitbekommen 😉
Zeig mal was du probiert hast und dann können wir dich auf den rechten Weg führen.

mfG Gü

11.02.2018 - 18:53 Uhr

Hallo lhyn,

was hindert dich daran das einfach auszuprobieren?
Bitte beachte [Hinweis] Wie poste ich richtig? Punkt 4.2 (und auch Punkt 1.1)

BTW: das Select kannst du dir sparen.

BTW 2: ein passendes Stichwort dazu ist "fluent interface".

mfG Gü

11.02.2018 - 16:56 Uhr

Hallo shrotty_ms,

dann ist die Aufgabenstellung schon Mist. Das kannst du mich ruhig zitieren 😉

Für das Problem (oben) hat Abt ja bereits die Stelle noch einmal erwähnt, welche die Ursache ist. Wo ist das Problem dabei?

mfG Gü

11.02.2018 - 15:19 Uhr

Hallo shrotty_ms,

Das alles muss mit einer struct-Konstruktion

Warum muss es ein struct (Werttyp) sein?

Eine Kiste ist kein Wert, sondern ein Objekt. Daher sollte Kiste auch als class deklariert werden.

Ein Wert ist eine Zahl, ein Punkt, etc. Eben alles das alleine als Wert für sich steht und keine Identität hat. Eine Kiste passt da eher nicht dazu.

mfG Gü

08.02.2018 - 19:53 Uhr

Hallo steven,

Die Orginaldateien müssen/solten irgendwie gespeichert werden

Ob die als Bytestrom (nichts anderes ist eine Datei) im Dateisystem, Netzlaufwerk, etc. liegen od. als Bytestrom in einer Datenbankzeile sollte in Bezug auf Dokumentationspflicht keinen Unterschied machen. Son sind sie auch sicher und können via DB-Backups (mit-) gesichert werden.

Falls sie jedoch irgendwo auf einem Netzlaufwerk liegen müssen, so kannst du den UNC-Pfad in der DB speichern.
Aber d.h. dann dass sich das Schema von der Netzlaufwerkspeicherung nicht ändern darf -- und das wird sich früher od. später sicher ändern und dann ist die Frage ob diese Änderung auch in der DB nachgepflegt wird.

Daher würde ich das gleich in der DB speichern und auf Nummer sicher gehen.
Wobei ich die Schwelle über 1 MB setzten würde, eher bei 5 MB -- lt. meiner Erfahrung gibt es da keine Probleme wenn diese direkt in der DB sind.

mfG Gü

08.02.2018 - 16:55 Uhr

Hallo steven,

Es sollen auch Zertifikate (in der DB) abgelegt werden

Nur damit es kein Missverständnis gibt: mit Zertifikaten meinst du hier jene von der Kalibrierung*?
Diese liegen dann als PDF (Scan) vor?

Da diese Dateien i.d.R. nicht recht groß sind, würde ich auch wie von Abt vorgeschlagen, das einfach als byte[] speichern. Ist einfach und direkt umsetzbar, alles direkt in der DB (ist für Backups praktischer), usw.

*

die einmal im Jahr zur Kalibrierung verschickt werden müssen

Kommt drauf an wo die hingeschickt werden -- vllt. ist Eichung gemeint.

mfG Gü

08.02.2018 - 15:16 Uhr

Hallo Konux,

eine Klasse "Datei" soll sich nicht ums CSV Lesen kümmern müssen -> Single-Responsibility-Prinzip -> daher einen CsvReader dafür verwenden

Die Klasse "Datei" sollte nur das darstellen was es ist. Eine Datei 😉
Also mit den Attributen (Properties / Eigenschaften) Name, Größe, etc.

Der CsvReader soll auch nicht den Bytestrom aus der Datei lesen und aufbereiten, sondern dies erledigt ein StreamReader, der vom CsvReader verwendet wird.

Das sind "allgemeine" OOP-Design-Regeln. Schau dir diese bei Bedarf / Gelegenheit an, dann wird sich das modellieren auch einfacher und natürlicher / logischer gestalen.

mfG Gü

07.02.2018 - 17:16 Uhr

Hallo Konux,

mal ein Klassendiagramm für ein Programm erstellt, welches eine .csv-Datei einließt, zerlegt und den Inhalt dann in Datenbanktabellen schreibt

Im angehängten Bild hast du eher den ganz groben Überblick dargestellt. Lt. Beschreibung sollten da jedoch Klassen wie CsvReader (od. CsvParser), Repository, etc. zu finden sein.

Modelliere das Ganze natürlich, so wie du es sagen würdest. Den Detaillierungsgrad kannst du auch selbst festlegen. Z.B. würde ich keinen FileSystemAdapter, o.ä. modellieren, denn das ist im CsvReader versteckt.

Schau dir UML Class Diagrams: Reference und die verlinkten Seiten an, da findest du ein paar Infos wie so etwas modelliert werden kann.

mfG Gü

07.02.2018 - 16:18 Uhr

Hallo mankingwwe,

alle Azubis nach mir dieses Projekt nachstellen können

Dann schreib das aber so gut es geht unabhängig von einer konkreten Technologie / Version. Denn sonst bist du mit der Dokumentation fertig und die dokumentierte Technologie ist schon wieder out.
Die Grundlagen (Klassen, etc.) ändern sich eh "nicht".
Aber alles was GUI, Datenbank, etc. (v.a. im Web-Bereich) angeht und schnell out-of-date. Achte darauf, denn sonst ist dieses Projekt umsonst.

mfG Gü

06.02.2018 - 14:00 Uhr

Hallo Abt,

das hast du wohl recht (in allen Punkten 😄).
Wenn dem so ist, dann ist eh eine ganze Menge vom .net-Stack dabei -- viel Spass damit...

mfG Gü

06.02.2018 - 13:37 Uhr

Hallo mankingwwe,

Habt ihr Ideen wie ich die unbearbeiteten Themenbereiche ins Projekt einbauen könnte? WPF-GUI für die Client-Anwendung, welche per MVC-Oberfläche (besser wäre [Artikel] MVVM und DataBinding statt MVC für WPF, MVC eignet sich für Web / Asp.net (Core) besser od. auch für WinForms) auf die Datenbank zugreift. Dass dabei Klassen, Properties, Felder, Methoden, Lambdas, sowie List / Array im Spiel sind ergibt sich zwangsweise.

Durch die AD-Verbindung -- unter der Annahme dass AD für Active Directory steht -- kann die Authentifizierung der Anwendung durchgeführt werden.

Bei Netzwerk TCP ist die Frage ob das explizit verwendet werden muss od. nicht. Implizit wäre das schon im Punkt AD-Verbindung abgedeckt 😉
Ich gehe aber von expliziter Verwendung aus. So könnte z.B. ein eigenständiger "Prozessor" für die Darstellung des Parkhauses erstellt werden. Dieser wird via Process.Start gestartet und die Host-Anwendung kommuniziert per TCP mit diesem "Prozessor". Damit dieser Prozessor nicht jedesmal das Parkhaus neu generieren muss (bzw. die Darstellung davon) cached er die erstellten Bilder im Dateisystem (-> Dateizugriffe und using mit File).

Aber was soll das konkret werden? Wenns eine Hausaufgabe ist, so frage besser beim Aufgabensteller nach wie und was konkret gewünscht ist.

mfG Gü

04.02.2018 - 21:24 Uhr

Hallo da_user,

ganz verstehe ich deine Frage nicht.

jede Datentabelle für sich in die Datenbank legen

Wie sonst? Od. ich verstehe eben wie gesagt die Frage nicht.

So wie ich die Frage weiters lese existiert die Datenbank noch nicht. D.h. du kannst wirklich "grün" beginnen. Somit modelliere deine Klassen (im DAL -- data access layer) so wie du sie brauchst und sie Sinn ergeben. Via EF werden diese dann in die DB gemappt.

Den DbContext kannst du dir als "unit of work" vorstellen. D.h. kapsle darin die Klassen die zusammengehören und die in der Verwendung auch zusammen benötigt werden. Somit kann es durchaus mehrere DbContexte in einer Anwendung geben. Das hängt voll und ganz von deiner Domäne ab und wie das modelliert wird. Ohne diese Kenntnis ist es schier unmöglich einen allgemein gültigen Rat zu geben.

Außerdem gibt es später immer noch die Möglichkeit bestimmte Code-Teile zu überarbeiten (vllt. im Zuge eine Refactoring), falls bemerkt wird dass der aktuelle Weg nicht ganz so ideal ist. Das geht mit agiler Entwicklung fast zwangsläufig einher...daher beginne einfach mti einem Weg und passe die Richtung immer wieder an.

die Views entsprechend nur in meinem C#-Code?

Views im Sinne von "read-only-Tabellen" würde ich eher als ViewModel in der Domänen-Logik abbilden. ViewModels sind nicht unbedingt auf WPF (vom MVVM) beschränkt, sondern können mehr od. weniger in jeder Anwendung verwendet werden um "Rohdaten" für die View od. sonst eine spätere Verarbeitungsschicht aufzubereiten.

mfG Gü

23.01.2018 - 15:37 Uhr

Hallo Gimmick,

dass nur ein Task asynchron läuft und die neuen Tasks, bis auf den neusten, verworfen werden?

speichere die Tasks in eine Liste*. Brich alle Tasks, außer den neuesten ab -> Cancellation mit der CancellationTokenSource.

* bzw. wenn es eh nur einen aktiven Task geben darf/kann, so reicht ein Feld aus.


using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private readonly IMyWorker      _myWorker;
        private Task<Result>            _activeTask;
        private CancellationTokenSource _cts = new CancellationTokenSource();

        public Form1(IMyWorker myWorker = null)
        {
            InitializeComponent();

            _myWorker = myWorker ?? new MyWorker();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.UpdateAsync();
        }

        private async void UpdateAsync()
        {
            if (_activeTask != null)
            {
                _cts.Cancel();
                _cts = new CancellationTokenSource();
            }

            _activeTask = _myWorker.UpdateAsync(_cts.Token);

            try
            {
                Result res = await _activeTask;

                label1.Text = res.ToString();
            }
            catch (OperationCanceledException) { }
        }
    }

    public class Result
    {
        public int Value { get; }

        public Result(int value) => this.Value = value;

        public static implicit operator Result(int i)      => new Result(i);
        public static implicit operator int(Result result) => result.Value;

        public override string ToString() => this.Value.ToString();
    }

    public interface IMyWorker
    {
        Task<Result> UpdateAsync(CancellationToken cancellationToken = default);
    }

    public class MyWorker : IMyWorker
    {
        private static int      _counter;
        private readonly Random _random = new Random();

        public async Task<Result> UpdateAsync(CancellationToken cancellationToken = default)
        {
            int i = _counter++;

            // Das lässt sich besser umsetzen ;-)

            cancellationToken.ThrowIfCancellationRequested();

            await Task.Delay(_random.Next(500, 1000));

            cancellationToken.ThrowIfCancellationRequested();

            return i;
        }
    }
}

Anmerkung: Das Ganze funktioniert, da sich in Result res = await _activeTask; das await nicht auf den _activeTask bezieht, sondern auf den TaskAwaiter<T> (ein Werttyp), der im Hintergrund durch die Compiler-Magic erstellt wird. Und dieser TaskAwaiter "treibt" die vom Compiler erstellte asynchrone Statusmaschine an. Daher kann der _activeTask ruhig gegen einen anderen ausgetauscht werden.

BTW: lagere die Berechnung od. was das ist in eine eigene Klasse aus.

mfG Gü

22.01.2018 - 19:17 Uhr

Hallo da_user,

BTW: asp.net core läuft auf dem raspberry pi (3) auch unter Linux (raspbian, Ubuntu getestet). Es ist sogar ein framework dependent deploy möglich.

mfG Gü

03.01.2018 - 14:19 Uhr

Hallo Turmoil,

Des Weiteren werden auch Geschwindigkeiten umgerechnet, also nicht nur Property x 25,4.

Gut, aber wo ist das Problem? Das lässt sich ja alles im Beispiel oben erweitern, nur ich mach das nicht mehr 😉

Da wäre als Weg besser nicht direkt den Zahlenwert, sondern den Wert (Zahlenwert + Einheit) als Eigenschaft zu haben, so dass dann beim Umrechnen auch der passende Kontext (Distanz, Distanz pro Zeit, Temperatur, etc.) vorhanden ist. Dazu einen passenden Typen erstellen und diesen verwenden und an den Konverter weiterreichen, der soll dann wissen wie umgerechnet wird.

einfach in der Binding-Klasse o.ä. also in der UI-Schicht abfrühstücken

Ich finde das gehört in das ViewModel. Im Forum gab es so eine Diskussion schon öfters (bezogen auf WPF, aber die Aussagen gelten auch hier): z.B. MVVM vs ValueConverter

Die View an sich ist und soll "dumm" sein und nur das Anzeigen was das ViewModel bereitstellt und in die andere Richtung dem ViewModel Benutzerinteraktionen weiterleiten.

PS: In WPF könnte die Möglichkeit per Converter / Binding verwendet werden, aber in WinForms ist das mehr Murks als Entwicklung. Daher würde ich diesen Weg erst recht nicht weiter verfolgen.

mfG Gü

03.01.2018 - 12:52 Uhr

Hallo Turmoil,

anbei eine Möglichkeit wie das mit der Basisklasse (ich habs BaseViewModel genannt) und per Expressions gehen kann. Den Code kannst du beliebig weiter ausbauen.


public abstract class BaseViewModel : INotifyPropertyChanged
{
    private static readonly Dictionary<Key, Delegate> _delegateCache;

    static BaseViewModel() => _delegateCache = new Dictionary<Key, Delegate>();

    protected virtual TProperty GetValue<TObject, TProperty>(TObject obj, string propertyName)
    {
        var key = new Key(typeof(TObject), propertyName, true);
        Func<TObject, TProperty> getterFunc = null;

        if (_delegateCache.TryGetValue(key, out Delegate del))
            getterFunc = del as Func<TObject, TProperty>;
        else
        {
            var getExpression = GetGetExpression<TObject, TProperty>(propertyName) as Expression<Func<TObject, TProperty>>;
            getterFunc        = getExpression.Compile();
            _delegateCache.Add(key, getterFunc);
        }

        TProperty value = getterFunc(obj);
        return value;
    }

    protected virtual void SetValue<TObject, TProperty>(TObject obj, string propertyName, TProperty value)
    {
        var key = new Key(typeof(TObject), propertyName, false);
        Action<TObject, TProperty> setterAction = null;

        if (_delegateCache.TryGetValue(key, out Delegate del))
            setterAction = del as Action<TObject, TProperty>;
        else
        {
            var setExpression = GetSetExpression<TObject, TProperty>(propertyName) as Expression<Action<TObject, TProperty>>;
            setterAction      = setExpression.Compile();
            _delegateCache.Add(key, setterAction);
        }

        setterAction(obj, value);
        this.OnPropertyChanged(propertyName);
    }

    private static Expression GetGetExpression<TObject, TProperty>(string propertyName)
    {
        ParameterExpression paramExpression = Expression.Parameter(typeof(TObject));
        MemberExpression propertyExpression = Expression.Property(paramExpression, propertyName);
        return Expression.Lambda<Func<TObject, TProperty>>(propertyExpression, paramExpression);
    }

    private static Expression GetSetExpression<TObject, TProperty>(string propertyName)
    {
        ParameterExpression paramExpression  = Expression.Parameter(typeof(TObject));
        MemberExpression propertyExpression  = Expression.Property(paramExpression, propertyName);
        ParameterExpression paramExpression2 = Expression.Parameter(typeof(TProperty), propertyName);
        BinaryExpression assignExpression    = Expression.Assign(propertyExpression, paramExpression2);
        return Expression.Lambda<Action<TObject, TProperty>>(assignExpression, paramExpression, paramExpression2);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    [DebuggerNonUserCode]
    private readonly struct Key : IEquatable<Key>
    {
        public Type Type           { get; }
        public string PropertyName { get; }
        public bool IsGetter       { get; }

        public Key(Type type, string propertyName, bool isGetter)
        {
            this.Type         = type;
            this.PropertyName = propertyName;
            this.IsGetter     = isGetter;
        }

        public bool Equals(Key other)
            => this.Type         == other.Type
            && this.PropertyName == other.PropertyName
            && this.IsGetter     == other.IsGetter;

        public override bool Equals(object obj) => obj is Key other && this.Equals(other);

        public override int GetHashCode()
        {
            unchecked
            {
                int hash = (int)17;
                hash = hash * 23 + this.Type.GetHashCode();
                hash = hash * 23 + this.PropertyName.GetHashCode();
                hash = hash * 23 + this.IsGetter.GetHashCode();
                return hash;
            }
        }
    }
}


public interface IMetricImpericalConverter
{
    double InchToMillimeter(double value);
    double MillimeterToInch(double value);
}

public class MetricImpericalConverter : IMetricImpericalConverter
{
    private const double OneInchInMM = 25.4;

    public double InchToMillimeter(double value) => value * OneInchInMM;
    public double MillimeterToInch(double value) => value / OneInchInMM;
}


public abstract class MetricalImpericalBaseViewModel : BaseViewModel
{
    private readonly IMetricImpericalConverter _metricImpericalConverter;
    private bool                               _isMetric = true;

    protected MetricalImpericalBaseViewModel(IMetricImpericalConverter metricImpericalConverter = null)
        => _metricImpericalConverter = metricImpericalConverter ?? new MetricImpericalConverter();

    public bool IsMetric
    {
        get => _isMetric;
        set
        {
            _isMetric = value;
            this.OnPropertyChanged(nameof(this.IsMetric));
        }
    }

    protected virtual double GetValue<TObject>(TObject obj, string propertyName)
    {
        double value = this.GetValue<TObject, double>(obj, propertyName);

        return _isMetric ? value : _metricImpericalConverter.MillimeterToInch(value);
    }

    protected virtual void SetValue<TObject>(TObject obj, string propertyName, double value)
    {
        if (!_isMetric)
            value = _metricImpericalConverter.InchToMillimeter(value);

        this.SetValue<TObject, double>(obj, propertyName, value);
    }
}


// Model
public class Rectangle
{
    public double Lenght { get; set; }     // [mm]
    public double Height { get; set; }     // [mm]
}

// ViewModel
public class RectangelViewModel : MetricalImpericalBaseViewModel
{
    private readonly Rectangle _rectangle;

    public RectangelViewModel(Rectangle rectangle) => _rectangle = rectangle;

    public double Length
    {
        get => this.GetValue(_rectangle, nameof(_rectangle.Lenght));
        set => this.SetValue(_rectangle, nameof(_rectangle.Lenght), value);
    }

    public double Height
    {
        get => this.GetValue(_rectangle, nameof(_rectangle.Height));
        set => this.SetValue(_rectangle, nameof(_rectangle.Height), value);
    }
}


public partial class Form1 : Form
{
    private readonly RectangelViewModel _viewModel;
    private readonly BindingSource      _bindingSource;

    public Form1()
    {
        InitializeComponent();

        var rectangle = new Rectangle { Lenght = 100, Height = 50 };
        _viewModel    = new RectangelViewModel(rectangle);

        // Der folgende Code könnte auch vom VS-Designer generiert werden, hier aber explizit zur
        // Veranschaulichung.
        _bindingSource = new BindingSource();
        _bindingSource.DataSource = _viewModel;
        lenghtTextBox.DataBindings.Add(new Binding(nameof(TextBox.Text), _bindingSource, nameof(_viewModel.Length), true, DataSourceUpdateMode.OnValidation));
        heightTextBox.DataBindings.Add(new Binding(nameof(TextBox.Text), _bindingSource, nameof(_viewModel.Height), true, DataSourceUpdateMode.OnValidation));
        metricCheckBox.DataBindings.Add(new Binding(nameof(CheckBox.Checked), _bindingSource, nameof(_viewModel.IsMetric), false, DataSourceUpdateMode.OnPropertyChanged));
    }
}

Den Code hab ich eben nur runterhackt, daher sind keine Argument-Validierungen, Tests, etc. dabei. Sonst lässt sich das sicher auch noch verbessern, aber als Idee sollte es reichen.

mfG Gü

28.12.2017 - 13:49 Uhr

Hallo ThomasE.,

für das konkrete Beispiel "( hier --> BeispielName)" hast du recht, aber nicht für "zur Laufzeit", denn nameof ist eine Compiler-Aktion, also zur Entwurfszeit.

Hallo andi_bln,

den Namen des Enums zur Laufzeit raus zubekommen ( hier --> BeispielName)

Woher bekommst du das Enum, so dass es zur Laufzeit nicht bekannt ist?
Wenn du es einer Methode übergibst, so ist es eh bekannt und dann kannst du wie von ThomasE. vorgeschlagen nameof verwenden.
Sonst schau dir auch die Enum-Methoden in der :rtfm: an ob dort etwas für dich dabei ist.

mfG Gü

28.12.2017 - 13:42 Uhr

Hallo BlackMatrix,

wozu soll das gut sein? Wenn die Komponente getestet ist, so soll / kann auch die Release-Variante verwendet werden. Idealerweise per NuGet.

Sonst kannst du ein eigenes NuGet-Paket für Debug erstellen und per MsBuild-Konfig (csproj ist so ein) per Condition je nach Debug/Release das passende NuGet referenzieren.
Die Umsetzung davon hängt davon ab ob das neue MsBuild-Format (Microsoft.NET.Sdk) od. das klassische MsBuild verwendet wird.

Den Punkt bzgl. VSTS kann ich nicht nachvollziehen, ich kenn mich aber bei VSTS nicht recht gut aus. Aber "private" NuGet-Feeds kannst du z.B. auch lokal, bei MyGet, etc. haben und so sollte das kein Problem sein.

Für die Komponente kannst du CD (continuous deployment) verwenden und ein NuGet-Paket zum Feed pushen wenn ein check in (od. ein Tag) durchgeführt wird.
So kannst du die neueste Version folglich auch im anderen Projekt nutzen.

mfG Gü

27.12.2017 - 20:11 Uhr

Hallo micha0827,

sind es ca. 50.000 Datensätze jede 5min die geschrieben werden

Sind die ca. 50.000 während der 5' od. eher als Art Batch die immer nach 5' geschrieben werden? Danach würde ich die Sicherung des Transaktionsprotokolls ausrichten.

Grob generell:
Full backup -> selten, da es viel Speicher braucht und lange dauert
Diff backup -> min. täglich
Translog backup -> sehr regelmäßig, da so auch Point-in-time Wiederherstellen möglich ist

Hast du dir für SQL Server 2016 auch schon die Doku zu High Availability (HA) angeschaut?

Ich bin mir noch nicht sicher was ich mit den älteren Daten mache, löschen möchte ich noch nicht, eventuell brauche ich die noch für Statistiken.

Verschieb diese in ein Archiv. Das Archiv kann in der gleichen DB sein od. du verwendest dafür ein eigene DB. Ich würde eher eine eigene verwenden, da so die Files der Live-DB besser verwendet werden können.
Das Verschieben kannst du per Job erledigen lassen od. manuell (per selbst erstelltem Tool), je nachdem ob die Daten einfach per "Timestamp" verschoben werden können od. nicht.

Es kommt vor allem auf die Art der Daten an, denn es wäre auch möglich gleich die Statistiken bzw. statistische Infos zu generieren und lediglich diese zu speichern. Achtung: die Rohdaten wären dann weg und du hängst an den extrahierten Infos fest -- dies kann u.U. ein Nogo für dieses Vorgehen sein, da du nie weißt was in Zukunft genau aus den Daten gelesen werden soll.
Da heutzutage Speicher ohnehin billig ist würde ich lieber die Rohdaten im Archiv behalten.

mfG Gü

27.12.2017 - 18:25 Uhr

Hallo jerome.blb,

als Einstieg schau dir Das Model-View-ViewModel (MVVM) Entwurfsmuster für WPF an, dann solltest du grob wissen was ein ViewModel (VM) ist und kannst dann gerne hier wieder nachfragen 😉

mfG Gü

27.12.2017 - 18:24 Uhr

Hallo micha0827,

hast du noch ein paar mehr Infos für uns? Wie z.B. wie groß wird die Schreibrate ca. sein, wird mehr gelesen als geschrieben, etc. Also wie die DB verwendet werden soll. Je nach dem kann es verschiedene Möglichkeiten geben.

mfG Gü

22.12.2017 - 12:07 Uhr

Hallo T-Virus,

eine Lösung die jede GPU ansprechen kann und automatischen Fallback auf die CPU hat wäre cool. Aber das müsste dann ein Abstraktion sein und Abstraktionen gehen eigentlich immer auf Kosten von Leistung. Ich bin auch davon begeistert und gespannt wie sich das entwickeln wird.

@Abt
Das Thema können wir per PN weiter verfolgen 😃

Das Thema finde ich auch interessiert. Ich würde mich freuen wenn das hier (bzw. in einem eigenem Thread) behandelt werden kann, da es wohl auch mehreren so gehen wird mit der Entscheidungsmöglichkeit Windows / Linux die dank .net Core gegeben ist.
Edit: dieses Thema wird in .net Core: Umstieg von Windows zu Linux behandelt

mfG Gü

22.12.2017 - 10:23 Uhr

Hallo,

Mit bisherigen Ansätzen war ich noch nicht sonderlich erfolgreich

Die Reise von .net zu GPGPU ist auf dem richtigen Weg. Von frühen Assembler-ähnlichen Ansätzen für die Kernels hin zu attributierten "üblichen" C#-Code. Das ist cool 😃

Zuletzt hab ich Alea GPU verwendet, Hybridizer muss ich noch evaluieren, aber schaut auf den ersten Blick schon gut aus.

Zitat von: Hybridizer: High-Performance C# on GPUs | Parallel Forall
you can benefit from the compute horsepower of accelerators without learning all the details of their internal architecture

So schön einfach die Abstraktion auch sein kann, ist es dennoch wichtig sich über die interne Architektur bzw. allgemeiner über Programmierung von GPUs zu informieren, damit keine Überraschungen drohen. Außerdem sollte gut überlegt werden was auf der GPU ausgeführt wird und ob sich das Problem, so wie es vorliegt, überhaupt für GPGPU passt od. angepasst werden muss od. überhaupt besser bei der CPU bleibt.

Nicht außer Acht gelassen werden darf auch der Umstand, dass GPGPU eben eine GPU verlangt und durch die verwendete Library auch oft ein Herstellerbezug besteht. Dies steht dem "run everywhere"-Gedanken, VMs und Containern etwas diametral gegenüber und muss daher berücksichtigt werden bzw. durch Fallbacks (auf CPU) abgedeckt werden. Azure, usw. bieten deshalb auch eigene VMs mit GPU-Unterstützung an.

Auch ist die Unterstützung von double oft nicht wirklich vorhanden und muss emuliert werden (durch nativ unterstützte floats). In aktuellen GPU- und Treiber-Generationen ist double jedoch vorhanden, allerdings ist aufgrund der internen Architektur, die Performance nicht so hoch wie bei float. Cf. Precision & Performance: Floating Point and IEEE 754 Compliance for NVIDIA GPUs

mfG Gü

20.12.2017 - 18:58 Uhr

Hallo MrSparkle,

viel zu schnell, um die angezeigte Nachricht zu lesen, bevor die nächste Meldung angezeigt wird.

Du könntest auch die Meldungen als Liste anzeigen, so ist die alte und die nächste sichtbar -- quasi ein Log.

mfG Gü

12.12.2017 - 09:09 Uhr

Hallo Kuklinski,

Coffeebeans Vorschlag lässt sich außerdem isoliert testen (Unit Tests) und so die Korrektheit der Prüfung sicherstellen.

Auch lässt sich so rascher auf geänderte / neue Anforderungen reagieren.

mfG Gü

07.12.2017 - 11:54 Uhr

Hallo HeikoAdams,

siehe auch myString == "" oder string.Length == 0, außerdem gibt es string.IsNullOrEmpty und string.IsNullOrWhitespace

Nimm die Variante die am leserlichsten ist und sofort klar macht worum es geht. Für mich wäre das eine der beiden Methoden, je nachdem wie mit Leerzeichen umgegangen werden soll.

mfG Gü

04.12.2017 - 10:24 Uhr

Hallo herbivore,

Bin ich gerade neben der Spur?

Ganz und gar nicht. Eine Umsetzung per Methode wäre das natürlichste für Zündhölzer. Zuerst eine Eigenschaft setzten (Aggregation) und dann die Methode ZuendeAn ausführen ist wohl etwas umständlich, wenn es direkt auch ginge.

Die Aufgabenstellung (oben) ist aber schon sehr abstrakt und lässt den Methodenaufruf außen vor (sehe ich so und wohl der OT auch).

mfG Gü

04.12.2017 - 09:27 Uhr

Hallo Silver80,

ja da hast du recht -- sorry wenn wir dich mehr verwirren als helfen. Mit der Anzahl der Möglichkeiten hast du auch recht und es kann sich so ergeben wie du sagst. Es kann gut sein dass gem. Evolution sich das wieder beruhigen wird, wenn sich bessere Wege herauskristallisieren. Aktuell kann ich mir das aber nicht so ganz vorstellen, das wird noch eine Weile dauern und in dieser Zeit gibt es wieder etwas Neues...

Gibt es zu Micro Service ein paar --> gut verständliche <-- Links um sich in die Sache einzuarbeiten ? Free eBook/Guide on ‘.NET Microservices – Architecture for Containerized .NET Applications’ und die Links in All about Microservices kann ich dir da empfehlen.

mfG Gü

03.12.2017 - 16:44 Uhr

Hallo Abt,

wie man da noch auf WCF beharren kann.

Wenn du mit "man" mich meinst, so zeig mir wo ich in diesem Thread auf WCF beharre. Und du kannst mich auch direkt ansprechen, wir kennen uns ja lange genug 😉
Solange WCF nicht definitiv tot ist, gehört es, mit samt der Abhängigkeit zu Windows und .net Full, eben auch erwähnt.
Ich glaub nicht dass WCF sterben wird -- das lese ich aus der GitHub-Issue, die mir bekannt ist, nicht heraus. Zumal es auch die Möglichkeit gibt WCF (Server) als open source Projekt weiter zu entwickeln. Und MS hat ihre Wege in Bezug auf .net Core auch schon öfters radikal geändert (project.json, asp.net Core und .net Full, etc.), vllt. es auch hier der Fall (hab dazu aber keinerlei Infos).

Wie du erwähnst gibt es bei asp.net Core Möglichkeiten, welche fast den gesamten WCF-Stack abbilden. Passt ja so.
Aber nur als Beispiel: wenn ich lokal eine IPC brauche*, so bin ich mit WCF besser dran, als mit asp.net Core. Da sehe ich weiterhin eine Daseinsberechtigung. Und wenn es über mehere Server geht, die noch dazu heterogen sein können, so -- ich wiederhole mich -- sehe ich WCF nicht als passend.

Im anderen Thread, beharre ich auch nicht auf WCF, sondern schreibe dass ich WCF nehmen würde, da ich damit am effizientesten zum Ziel komme.

Gegen asp.net Core, etc. spreche ich mich auch nicht aus, aber du versuchst mir das unterzuschieben (kommt mir halt vor).
Je nach Anforderung nehme ich das Mittel her, mit dem ich am effektivsten weiterkomme.

Wenn es neue Mittel und Wege gibt, so ist das gut, aber nur weil sie "in" sind, ist das noch kein ausreichendes Argument sie als besser zu betrachten wie bisherige Mittel.
Dabei sollte und muss aber betrachtet werden warum etwas "in" ist. Ist es nur "in" weil es gehypt wird bzw. werden muss, so ist das schön, bringt aber nichts. Ist es "in" weil aus bisherigen Methoden / Ansätzen gelernt wurde und die Verwendung für das Aufgabengebiet einfacher und passender wird, so ist das gut und tatsächlich ein Grund dass es "in" ist.
Ich bin weder naiv, noch so konservativ dass ich mit Biegen und Brechen an bestehenden Technologien hänge. Aber solange neue Technologien, bezogen auf die Anforderung, keinen nennenswerten Vorteil bringen schmeiß ich eine bestehende Technologie nicht über Bord.

Die Entwicklung von .net Core macht durchaus Sinn und ich begrüße die. Darin gibt es ein paar super Ansätze die mir sehr gut gefallen und bestimmte "Dinge" besser als in .net Full gelöst wurden (asp.net Core ist endlich vernüftig und hat nur einen Controller anstatt zwei, DI ist dabei, Logging ist besser, weit mehr Abstraktionen, usw.).
Zumal auch aus der Erfahrung mit .net Full jede Menge gelernt wurde und dies in die neue Entwicklung mit einfließen konnte. Andererseits war die Entwicklung von .net Core nötig um für Container- und Cloud-Einsätzte besser od. überhaupt gewappnet zu sein. (Ich weiß dass dir das mehr als genau bekannt ist.)

Es gibt jedoch auch eine .net-Welt außerhalb der Cloud und außerhalb von Containern bzw. eine die auf Windows beschränkt ist.
Und warum sollte ich hier auf eine Möglichkeit verzichten, nur weil sie nicht mehr "in" ist?

Wie oben erwähnt glaube ich nicht dass WCF sterben wird. Ich glaub aber auch nicht dass es 1:1 in .net Core übernommen werden wird, falls überhaupt. Da kann ich mir eher vorstellen, dass es eine "Core"-Version geben wird, die eben auch aus der Erfahrung gelernt hat und bestimmte unhandliche Punkte von WCF besser löst bzw. überhaupt weglässt, da sie selten bis kaum benötigt werden.

mfG Gü

* auch in Zeiten von Micro-Services, etc. sind diese nicht überall passend und eine klassische IPC kann noch angebracht sein

PS: .net Core und asp.net Core verwende ich auch produktiv in verschiedenen Umgebungen, da hänge ich nicht unbedingt an .net Full

02.12.2017 - 21:41 Uhr

Hallo Abt,

täusch dich mal nicht 😉
Ich sehe es nicht allgemein anders, nur je nach konkretem Kontext.
Da du auf Windows Dienst mit WCF oder Alternative anspielst (hatte ich extra nicht verlinkt, damit die (ziellose) Diskussion nicht neu durchgemacht werden braucht), so würde ich dort -- Windows-Service lt. Frage -- WCF nehmen.

Hier sehe ich die Frage aber eher allgemein und zur Orientierung des OT, daher ist meine Antwort auch neutral, sogar eher Richtung HTTP-basierten Diensten, ausgefallen.

Bin ich aufgrund der Rahmenbedingungen, wie z.B. IT-Richtlinien, Intranet, etc., auf Windows beschränkt, so ist für mich WCF eine Option.
Bin ich aber in den Rahmenbedingungen freier und weiß nicht was kommen wird (in Hinsicht auf potentielle Clients), so ist ein HTTP-basierter Dienst die bessere Wahl. Kann ich Azure, etc. nutzen, so ist meine Wahl auch klar, und es ist nicht WCF...
Im anderen Thread hab ich das auch nicht anders dargestellt.

SOAP braucht, was mit das letzte Argument für WCF bislang war

Aber nicht von mir. Von SOAP an sich halte ich nicht viel, da es ja trotz Protokoll und Standard leider nicht mit verschiedenen Plattformen / Technologien einwandfrei klappt.

mfG Gü

02.12.2017 - 18:31 Uhr

Hallo Silver80,

klassisch wird dein Server als "Application Server" bezeichnet. Grob schaut das so aus:


+--------+       +--------------------+        +----+
| Client | ----> | Application Server | --+--> | DB |
+--------+       +--------------------+   |    +----+
                                          |
                                          |    +----------------+
                                          +--> | anderer Dienst |
                                               +----------------+

Aktuell gibt es aber einen Trend hin zu "Micro services", indem mehrere kleine "Application Server" vorhanden sind und die nur eine Aufgabe übernehmen. Dies hat u.a. den Vorteil dass dieser Mini-Service isoliert entwickelt und getestet werden kann. Aber auch den Nachteil, dass eben mehrere Services betreut werden müssen.
Schaut z.B. so aus (es gibt hier viele Möglichkeiten):


                                           +-----------------+       +----------------+
                                      +--> | Micro Service 1 | ----> | anderer Dienst |
+--------+       +----------------+   |    +-----------------+       +----------------+
| Client | ----> | Service Facade | --+    ...
+--------+       +----------------+   |    +-----------------+       +----+
                                      +--> | Micro Service n | ----> | DB |
                                           +-----------------+       +----+

schreibe ich den Server in c#?

Klar 😉

was nehme ich als Server?

Da gibt es viele Möglichkeiten und die hängen v.a. auch davon ab auf welche Plattform du dich "festlegen" möchtest.

Rein Windows -> Asp.net Core WebAPI od. WCF
.net Core (Windows, Linux, MacOs) -> Asp.net Core WebAPI (ev. in einem Docker Container)
Cloud / Azure -> Asp.net Core WebAPI gehostet und in einem App-Service od. per Azure Functions

Und was zur Kommunikation?

Alle Varianten basieren auf HTTP.
Die oben erwähnten Micro-Services können somit auch in einer anderen Sprache / Technologie erstellt werden, da HTTP wirklich plattform- und technologieunabhängig ist.

WCF bietet auch TCP, Named Pipes, Message Queues an, aber bei WCF bist du auf Windows beschränkt.

Es kommt also darauf an was du genauer willst, denn einen einzigen Königsweg gibt es nicht.

Wenn du die Zeit hast, so schau dir alle Variante an, denn dadurch lernst du eine Menge und kannst du selbst ein gutes Bild über die einzelnen Möglichkeiten mit den Vor-/Nachteilen und deren potentiellen Einsatzmöglichkeiten bilden.

Bei allen Variante würde ich für den Client eine Fassade bereitstellen, welche zum Einen den Zugriff auf den/die "Server" wegabstrahiert und den Zugriff auch einfach möglich macht.
So lässt sich der Server auch mit geringen Aufwand (für den Client) tauschen und zudem kann der Client besser getestet werden, da der Server bzw. dessen Fassade einfach gemockt werden kann.

mfG Gü

01.12.2017 - 10:32 Uhr

Hallo susisorglos,

Ist die ClickOnce Bereitstellung dazu überhaupt in der Lage?

Nein, denn ClickOnce installiert pro Benutzer in einem von ClickOnce verwalteten Pfad. Für deine Anforderung brauchst du eine andere Setup-Lösung. Das muss nicht unbedingt InstallShield sein, es gibt dazu genügend -- z.B. WiX, ...

mfG Gü

28.11.2017 - 18:17 Uhr

Hallo texMan,

nützliche Funktionen mit Dialogen

Meinst du den Dialog mit C# erstellen und dann in VBA verwenden?
Auch wenn ich da keine praktische Erfahrung habe, so wäre das wohl via COM möglich.

Generell würde ich aber keine UI / Dialoge bereitstellen, sondern nur die Logik dahinter und die UI in der "Zielplattform" erstellen.
Da aber eine .net-Dll ohne COM ohnehin in VBA nicht verwendet werden kann*, so können UI / Dialoge schon bereitgestellt werden.

Je nach Art deiner "nützlichen Funktionen" könntest du auch überlegen ob du diese nicht allgemeiner per Service (HTTP geht in VBA) bereitstellst, so dass du nicht auf COM beschränkt bist.

* ich gehe davon aus dass dies immer noch stimmt

mfG Gü

27.11.2017 - 12:05 Uhr

Hallo Gerri3d,

indem du von der Tab-Page das Paint-Ereignis abonnierst und dann in dessen Event-Handler zeichnest.
Siehe [FAQ] Eigenen Event definieren / Information zu Events (Ereignis/Ereignisse)

In VS schau dir da bei den Eigenschaften der Tabpage die Ereignisse an (dort wo der Blitz ist).
Ähnlich wie du ein Button-Klick behandelst.

Bitte beachte bei weiteren Fragen auch [Hinweis] Wie poste ich richtig? Punkt 1, denn das sind schon elementare Grundlagen.

mfG Gü

27.11.2017 - 10:32 Uhr

Hallo Olii,

Wie müsste ich dann so ein Klassendiagramm zeichnen?

Siehe angehängtes Bild.

Auf der Streichholz-Seite:* 1 Steichholz kann mehrere anzünden

Auf der Streichhölzer-Seite:* mehrere Streichhölzer können von einem angezündet werden -> 1-Ende

  • ein od. mehrere Streichhölzer können auch nicht angezündet werden -> 0-Ende

mfG Gü

27.11.2017 - 10:20 Uhr

Hallo Gerri3d,

indem du im Paint-Ereignis der Tab-Page zeichnest. Das Zeichnen an sich ist genau gleich wie bisher. Nur eben nicht in OnPaint (bzw. im Paint-Ereignis der Form, Panel, etc.), sonder von jenem der Tab-Page.

mfG Gü

26.11.2017 - 19:53 Uhr

Hallo Olii,

mit der Aggregation hast du recht.

würde gerne wissen wie Ich das rausfinden kann.

Über die "Lebensdauer" der Objekte.
Bei der Komposition ist alles kaputt / tot wenn die 1-Seite kaputt / tot ist.
Bei der Aggregation kann die n-Seite noch leben, wenn die 1-Seite kaputt ist.

Wenn ein Streichholz viele andere anzünden kann, so können auch noch welche übrig bleiben, daher Aggregation.

Wenn ein Haus gesprengt wird, so sind auch alle Räume kaputt, daher Komposition.

mfG Gü

24.11.2017 - 17:30 Uhr

Hallo KleeSchulz,

WinForms od. WPF? Grid-/Table-Steuerelemente gibt es da genug und idealerweise per Datenbindung.

Schau mal ob du zu diesen Stichwörtern etwas für dich passendes findest.

mfG Gü