Laden...

Forenbeiträge von Taipi88 Ingesamt 1.029 Beiträge

15.05.2019 - 14:32 Uhr

Hi,

parallelisiert war das schon - hab erst einmal Parallel.ForEach ohne manuelle Anpassungen des MaxDegreeOfParallelism verwendet. (Muss noch testen, ob weitere Einschränkungen hier weitere Besserung bringen könnten) Die 800 MB/s an Durchsatz kamen nahezu ausschließlich vom Testprogramm. (Hatte hier eigentlich erwartet, dass Parallel.ForEach keine so tolle Idee ist - aber scheinbar ist es kein schlechter Start)

Trotzdem vielen Dank für den Hinweis.

LG

15.05.2019 - 13:44 Uhr

Hi,

naja - in diesem Fall ist das ganze ein Raid10 - mit einem Durchsatz von 800 MB/s geht da schon ein bisschen mehr wie nur über eine Platte - Fakt ist nach ersten Tests jedenfalls definitiv, dass der Flaschenhals dennoch der Datenspeicher bleibt.

Wenn das ganze etwas länger dauert wird man bei uns letztlich damit leben müssen - möchte jedoch bei der Datenmenge natürlich trotzdem möglichst effizient vorgehen. Nach Erfassung der urspünglichen Prüfsumme bzw. Hashwert reicht es völlig aus, dass danach jede Datei alle 30 Tage geprüft wird - würde hier entsprechend partitionieren, dass täglich ein kleinerer Teil überprüft wird. (Hier dann auf Basis der Größe der Dateien)

Größe und Zeitstempel sind (auch in meinen Augen) eigentlich kein absolut verlässlicher Indikator für unveränderte Dateien - sicher - der Fall, dass sich dort versehentlich etwas ändert ist in der Theorie selten - aber letztendlich heißt das ja nichts.

Nunja - das erstellen einer Adler32-Prüfsumme für ca. 1TB dauert nach ersten Tests ungefähr 20 Minuten (MD5 und SHA1+2 ähnlich) - damit wäre theoretisch sogar täglich ein kompletter Scan (noch) machbar - da hier allerdings nicht erforderlich - seh ich mit bei einem 30-Tages-Fenster genug Luft für weiteren Wachstum des Datenspeichers. (Werde die Zeit zwar sicherlich noch steigern, da das Ganze reines Prüfsummen berechnen ist - aber selbst wenn's eine Stunde pro TB dauert geht das denke ich in Ordnung)

LG

15.05.2019 - 10:33 Uhr

Hi,

ich soll eigentlich zum Abschluss eines jeden Prüfzyklus eine Zusammenfassung der geänderten Dateien bzw. eine "Erfolgsmeldung", dass sich nichts geändert hat per Mail schicken. Ich schätze mal eine halbwegs übersichtliche Zusammenfassung des Ergebnisses mit anpassbarem Layout mit vorhandenen Tools ist eher schwierig 😕 Ich schau mich dennoch mal um.

Die Größe der Datei darf allerdings in diesem Fall nicht bewirken, dass diese Datei als unverändert betrachtet wird, hiermit darf man dann lediglich ausschließen, dass das Errechnen einer Prüfsumme/Hashwerts erforderlich ist, da die Datei definitiv verändert wurde.

Ich werde jetzt erstmal ein wenig rumtesten, ob ich mit Adler32 und MD2 glücklich werden könnte. Falls nicht muss ich wohl oder übel intervenieren, dass das auf dieser Basis vll zu viel gewollt ist.

LG und Vielen Dank

14.05.2019 - 15:53 Uhr

Hi,

ich habe eine Spezialaufgabe bekommen, in deren Rahmen ich den Inhalt eines recht großen Verzeichnisses (12TB+) überwachen muss.

Die Dateien sollten prinzipiell nicht geändert werden - und wenn doch muss ich das feststellen und merken. Soweit so gut - ich würde als hingehen - jede Datei hashen, den Hash speichern und dann ungefähr einmal pro Monat jede Datei prüfen und ggf. Änderungen melden.

Nun - da das Verzeichnis so riesig ist wird das Berechnen der Hashes eine ganze Weile dauern, was die Frage nach dem "richtigen" Hashverfahren recht wichtig macht in meinen Augen. Und hierzu bräuchte ich ein paar eurer Tipps und Erfahrungen.

Über die Dateien: Die meisten sind ca. 75MB aufwärts - spontan würde ich hier erst mal auf md5 tippen - mir stellt sich allerdings die Frage ob hier CRC32 ebenfalls angebracht wäre und ob es ggf. noch weitere - eventuell gar schnellere und ausreiched "robuste" Hashverfahren gibt.

Vielen Dank im Voraus.

14.05.2019 - 14:37 Uhr

Hi,

ich sehe zwar keine Erklärung in diesem Thread warum das nicht geht - aber nach Abt scheint es um asynchrone Jobs zu gehen.

Wenn du Caching/Tracking umgehen möchtest gibt es verschiedene Wege - du kannst dir folgende Seite mal anschauen, falls das mit dem neuen DbContext alleine nicht reicht:
https://codethug.com/2016/02/19/Entity-Framework-Cache-Busting/

LG

14.05.2019 - 13:40 Uhr

Hi,

mehrere Contexte sind problemlos möglich wenn man die Daten intelligent anpackt.

Wenn du allerdings an verschiedenen Stellen die selben Daten pro Request anpackst - dann machst du dir natürlich nur Ärger. Allerdings wäre dann in meinen Augen nicht der erste Versuch die Daten frisch abzuholen - sondern den Datenzugriff eher derart zu gestalten, dass man die Daten nicht an verschiedenen Stellen derart anpackt...

LG

14.05.2019 - 12:58 Uhr

Hi,

du solltest dir noch mal anschauen, wie man das in WPF besser macht. Wenn du so weiter machen möchtest wie jetzt wäre in meinen Augen WindowsForms besser geeignet als WPF.

Wie man das richtig macht: [Artikel] MVVM und DataBinding

Abseits davon: Für C#-Code bitte C#-Tags benutzen - für XAML gibts XML-Tags - macht's übersichtlicher für die Leser - ich bezweifle nämlich, dass jemand versucht deinen Code so zu lesen...

Edit:
Ja der Beitrag ist kurz und auf den ersten Blick nicht direkt hilfreich - dennoch nicht bös gemeint - denn wer den Artikel liest und umsetzt wird schnell feststellen, dass dies die korrekte Art ist mit WPF zu arbeiten. Die Arbeit wie sie in WinForms oft gemacht wird - ist unter WPF schlicht nicht angebracht. Im Normalfall sollte auf diese Art das Problem nicht mehr auftauchen - und selbst wenn es das doch tut - kann man bei Anwendung von MVVM und CodeTags ernsthafte Hilfe erwarten und hat zusätzlich den Vorteil, dass es plötzlich ganz viele Tutorials gibt die zur eigenen Arbeit passen.

14.05.2019 - 08:23 Uhr

Hi,

du liegst richtig, dass das mit einer einzigen Schleife schwierig darstellbar ist. Auf der anderen Seite: Warum nicht mehr als eine Schleife? Deine Optionen lassen sich bislang immer gut als "KeyValuePair<int, string>" darstellen. Das würde zumindest für hart gecodete Optionen sehr simpel funktionieren.

Wenn du die Generierfunktion universeller haben möchtest würde ich empfehlen eine Klasse für die Optionen zu erstellen, die einen Namen und eine List von KeyValuePair<int, string> hat. Anschließend würde ich das kartesische Produkt bilden und aus den so entstandenen Konfigurationsmöglichkeiten den letztendlichen Exportstring bauen. (Die Arbeit hier in 2 Methoden zu splitten sollte das Ganze deutlich übersichtlicher halten)

Da du das ganze wahrscheinlich eh noch stark an deine Bedürfnisse anpassen musst mal ein Beispiel wie das bei mir aussehen würde (ohne das String-Gefrickel):


namespace ConsoleApp8
{
    class Program
    {
        public static void Main(string[] args)
        {
            KeyValuePair<string, string> prefix = new KeyValuePair<string, string>("GO", "VW Golf");
            var group1 = new OptionGroup("Motor", new KeyValuePair<int, string>[]
            {
                new KeyValuePair<int, string>(1, "TSI"),
                new KeyValuePair<int, string>(2, "TDI")
            });
            var group2 = new OptionGroup("Farbe", new KeyValuePair<int, string>[]
            {
                new KeyValuePair<int, string>(1, "Weiß"),
                new KeyValuePair<int, string>(2, "Schwarz"),
                new KeyValuePair<int, string>(3, "Rot")
            });

            var product = CartesianProduct(new[]{group1, group2 }.Select(g => g.Options));
        }

        // Source: https://stackoverflow.com/questions/3093622/generating-all-possible-combinations
        static IEnumerable<IEnumerable<T>> CartesianProduct<T>(IEnumerable<IEnumerable<T>> sequences)
        {
            IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>()};
            return sequences.Aggregate(emptyProduct,
                (accumulator, sequence) => 
                    from accseq in accumulator 
                    from item in sequence 
                    select accseq.Concat(new[] {item})                          
                );
         }
        static StringBuilder GenerateExportString(KeyValuePair<string, string> prefix, IEnumerable<IEnumerable<KeyValuePair<int, string>>> options)
        {
            var sb = new StringBuilder();
            foreach(var selection in options)
            {
                // hier deinen export-string zusammenschustern, jede "selection" ist dabei eine Konfigurationsmöglichkeit und enthält somit alle Id's und Namen der dafür gewählten Option
            }
            return sb;
        }
    }

    public class OptionGroup
    {
        public string Name {get;set;}

        public IEnumerable<KeyValuePair<int, string>> Options {get; }

        public OptionGroup(string name, IEnumerable<KeyValuePair<int, string>> options)
        {
            Name = name;
            Options = options;
        }
    }
}

26.04.2019 - 10:31 Uhr

Hi,

je nach Projekttyp kommt dort nicht immer eine exe - sondern teils auch eben nur eine dll raus.

Das Thema in deinem Fall ist Folgendes:
NetCore erstellt meist eigentlich nur eine dll, welche mit Hilfe der Runtime (dotnet.exe) ausgeführt wird - das ist auch gut so, weil diese dll portabel ist und auf mehreren Betriebssystemen ausgeführt werden kann. (das gilt jedoch nicht für eine eventuell erzeugte .exe auf Basis von .Net Core)

Wie du trotzdem eine exe erzeugen kannst - solltest du googeln und dir auch gut überlegen welches Runtime-Target du wählst.

LG

24.04.2019 - 11:44 Uhr

Kein Ding - dass das in Tutorials nicht vorkommt ist logisch, da .NET-Core sehr jung ist und potenziell eher für Serveranwendungen (die im Einsteigertutorial sicher nicht vorkommen). Ab davon - so groß wie .NET / .NET Core / .NET Standard geworden ist - ist es unumgänglich, dass es für Einsteiger erstmal sehr unübersichtlich wirkt 😉

Viel Erfolg jedenfalls 😉

24.04.2019 - 11:19 Uhr

Hi,

nein - auch .NET kannst du problemlos mit der Community-Edition nutzen. Eigentlich fehlen in der Community-Edition ohnehin nur Spezialsachen, die du noch lange nicht brauchst.

Wie du .NET benutzt? Simpel indem du die richtige Projektvorlage nimmst. Es gibt halt mehr wie eine Möglichkeit für Konsolenprogramme - und du musst eben die auswählen, die .NET benutzt. (In VS 2019 heisst die Vorlage "Konsolen-App (.NET-Framework)")

Du hast z.B. eine Vorlage ausgewählt die "Konsolen-App (.NET Core)" oder ähnlich heißt.
(Für deinen Fall also nicht ganz die richtige Vorlage)

LG

24.04.2019 - 10:13 Uhr

Hi,

urgs - du benutzt kein .NET - sondern .NET Core.
Unter normalem .NET hätte es ohne einen Verweis auf System.IO.Ports.dll geklappt, da die Assembly Teil der System.dll ist. (habs unter .NET 4.7.2 ausprobiert)

Unter .NET Core läuft das allerdings anders - hier verwendet man größtenteils NuGet - du musst somit über den NuGet-Paketmanager das Paket System.IO.Ports hinzufügen.

Übrigens: An deiner Stelle würde ich vermutlich eher mit .NET und nicht mit .NET Core anfangen - früher oder später wirst du Anwendungen mit UI schreiben sollen wenn du einem Buch folgst - das ist in dieser Form mit .NET Core nicht möglich.

LG

23.04.2019 - 15:14 Uhr

Hi,

als Starthilfe: Du solltest solang du's noch nicht auswendig kannst immer die MSDN-Doku benutzen. Google nach "c# serialport" liefert ganz oben folgendes Ergebnis:
https://docs.microsoft.com/de-de/dotnet/api/system.io.ports.serialport?view=netframework-4.8

Ganz oben sieht man dann:
Namespace: "System.IO.Ports" -> du schreibst dann "using System.IO.Ports"
Assemblies: "System.dll, "System.IO.Ports.dll"
Da System.dll im Standard eingebunden ist, benötigst du nur noch einen Verweis auf "System.IO.Ports".

LG

23.04.2019 - 12:28 Uhr

Hi,

mal abseits der von Abt angemerkten Sachen:
Ich sehe in deinem Post eine (Teil)Erklärung, was du gerne machen möchtest.
Was ich vermisse: Deine Problembeschreibung 😉

Ein weiteres, wichtiges Stichwort wäre hier: "DataBinding" - auf die Art, die du hier verwendest brichst du dir nur selbst das Genick - Spaß macht das sicher keinen sowas zusammenzuschreibseln...

LG

16.04.2019 - 12:50 Uhr

Hi,

wer hat denn das XML verbrochen? Ich hoffe nicht du?

Normalerweise sollte da nämlich nicht

<user0></user0>

sondern eher etwas Richtung

<user id="0">...</user>

stehen - das vereinfacht die Verarbeitung nämlich um ein vielfaches...
(Hier könntest du dann nämlich XPATH oder sogar Deserialisierung anwenden...)

Als Beispiel wenn das XML so bleiben sollte:


static void Main(string[] args)
        {
            string xml = "<users><user0><name>MARY</name><time>03:23:23</time></user0><user1><name>BETTY</name><time>04:54:10</time></user1></users>";
            XElement xelem = XElement.Parse(xml);
            var users = xelem.Elements(); // holt die direkt untergeordneten Elemente von "users"
            foreach(var userEntry in users)
                Console.WriteLine(userEntry.Element("name").Value);
            Console.ReadLine();
        }

LG

11.04.2019 - 07:25 Uhr

Hi,

hab nur das OpenBook verlinkt, weil es frei verfügbar ist und dich auch erst mal reinschnuppern lässt ob das für dich passt - für einen Kauf definitiv die aktuelle Version.

LG

10.04.2019 - 16:26 Uhr

Hi,

ich hab mir damals http://openbook.rheinwerk-verlag.de/visual_csharp_2012/ als echtes Buch gekauft, weil ich das komfortabler fand. (War glaub noch die 2008er Version)

Das gibt zumindest mal einen ziemlich umfassenden Einblick und hat anfangs auch als Nachschlagwerk gedient 😉

LG

10.04.2019 - 15:08 Uhr

Hi,

nun - Anfänger ist ein weites Feld - aber den echten Einstieg muss man auch irgendwann schaffen 😉

Grundsätzlich würde ich dir ehrlich gesagt empfehlen zum Thema C# nicht nur Videos zu schauen - sondern auch ein Buch durchzuarbeiten.

Sich in Word auszutoben würde ich eigentlich keinem Anfänger empfehlen obwohl ich das selbst recht früh gemacht habe. Es gibt zum einen ein ohnehin schon nicht unkompliziertes Objektmodell, sondern sogar noch verschiedene Methoden überhaupt mit Word zu arbeiten - du wirst entsprechend langsame Fortschritte machen.

Dir jedoch würde ich es empfehlen - denn es gibt nichts besseres zum Lernen als sich selbst Anwendungen zu schreiben.

Mal als Starthilfe zum Googeln:
a) "Word interop edit document"
b) "Word openxml edit document"

(Das sind quasi die beiden beiden bekanntesten Möglichkeiten mit Word bzw. Word-Dateien zu arbeiten)
"Interop" lädt in diesem Fall Word selbst und steuert dieses fern.
"OpenXml" wiederum bearbeitet das Dokument selbst. (Dürfte am Anfang unübersichtlicher sein, obwohl es zum Beispiel im Serverbereich deutliche Vorzüge hat)

LG

05.04.2019 - 15:05 Uhr

Hi,

da die Antwort auf deine letzte Frage etwas kurz ausfiel:

Generell arbeitet man bei WPF nach dem MVVM-Pattern - Ziel des Ganzen ist es eine gewisse Entkopplung von Ansicht und Ansichts-Logik zu erreichen. Events zu abonnieren bedeutet zwangsläufig C#-Code - Code der in WPF generell vermieden wird. (Das perfekte XAML-Fenster hat z.B. überhaupt keinen eigenen C#-Code - sondern ein ViewModel, welches über XAML verbunden wird)

Die meisten Controls lassen es unter WPF zu, dass man an Stelle von Events zu abonnieren - Commands aus dem ViewModel anbindet, womit eine harte Binding des ViewModels an die View unnötig ist.

LG

04.04.2019 - 16:00 Uhr

Hi,

kurz und knackig: Hör bitte auf das so zu machen.

Warum?
a) HTML (das jederzeit geändert werden kann) auszulesen ist generell nicht der optimale Ansatz und eine Notfallösung
b) DHL bietet für Privat und Geschäftskunden extra eine API zur Sendungsverfolgung an

Erstell dir am besten ein Konto auf https://entwickler.dhl.de/ - lies dich ein - und bau was gescheites 😉

LG

04.04.2019 - 12:57 Uhr

Hi,

um genau zu sein sprichst du die "Non-Client Area" an - die lässt sich unter WPF auch entsprechend anpassen - das ist zwar für einen Anfänger nicht unbedingt so leicht - letztendlich aber gut dokumentiert.

Die Themen sind zwar alle eher auf "Skinning" ausgelegt - bieten aber letztendlich was du möchtest: Funktionalität beibehalten - aber mit anderem Aussehen.

Zum Einstieg kannst du dir die beiden Sachen mal anschauen:

LG

03.04.2019 - 09:59 Uhr

Hi,

naja - das hängt stark von der Umgebung ab. Wenn das auf Client-Computern geschieht, die ohnehin Office zur Verfügung haben - wäre sogar Office selbst eine durchaus gangbare Lösung - alternativ geht in einem solchen Fall auch ein automatisierter Druck auf einem entsprechenden PDF-Printer. (Beides wäre mehr oder minder kostenneutral möglich)

Falls das beides nicht sinnvoll möglich ist - wirst du eine Lib brauchen, die das für dich tut - ich vermute allerdings, dass die guten nicht kostenlos verfügbar sein werden und es auch dort zig verschiedene Wege gibt...

LG

03.04.2019 - 09:32 Uhr

Hi,

nein - ViewModels generieren i.d.R. keine Models nur um diese zu speichern. Sie arbeiten lediglich damit.

Schau dir doch bitte mal wirklich die verlinkten Seiten zum Thema MVVM und 3-Schichten-Architektur an - dann stellt sich dir diese Frage gar nicht mehr...

LG

03.04.2019 - 08:43 Uhr

Hi,

nun - wenn man dort nach der Beschreibung geht - spielt es keine Rolle ob du Equals überschreibst oder nicht - sondern vielmehr welche Eigenschaften gespeichert wurden und dass eben das korrekte Element ausgewählt wird.

Welche Eigenschaften das Ding nun hat bestimmst du - und welches Objekt beim nächsten Start ausgewählt wird - könnte eine Guid sein, die du dir an anderer Stelle merkst. Alles kein Grund Equals und GetHashCode zu überschreiben.

LG

03.04.2019 - 07:12 Uhr

Hi,

mal von MVVM weg was mich an deinem Problem verwirrt:
Ja - beim Serialisieren und wieder Deserialisieren ändert sich der Verweis, den Equals verwendet - so weit - so gut. Aber warum in aller Welt ist das überhaupt von Belang?

Mischst du verschiedene Datenquellen, in denen sich dann Duplikate der deserialisierten Elemente befinden? Falls ja hätte dir der hier gezeigte Code kein Stückchen weitergeholfen 😕 (Es bringt ja nichts auf Basis eines Namens zu vergleichen, der sich offenbar auch jederzeit ändern kann - was du dann bräuchtest wäre eine unveränderliche Id)

Falls dem so ist - solltest du denke ich besser beschreiben was du eigentlich machst und vorhast - möglicherweise gibt es einen deutlich besseren Weg, der dir entsprechende Probleme spart.

Was deine Implementierung angeht: Du beschreibst lediglich einen Aufbau den mal wohl VVM nennen könnte - denn das zugrunde liegende Model fehlt ja. Allerdings würde dir das allein hier auch nicht weiterhelfen...

LG

02.04.2019 - 15:31 Uhr

Hi,

gut - dann meinst du die Standard-Refactorings - hab hier ReSharper im Einsatz - der hat mir solchen Unsinn noch nicht vorgeschlagen...^^

Zurück zum Thema:
Grundsätzlich sieht dein Code so aus, als ob weder Equals noch GetHashCode überschrieben werden müssten - denn beide machen im Original ihren Job wie sie sollen ohne dass du an Funktionalität verlierst.

Falls VS dir beides generiert hat: Würde ich so nicht mehr verwenden. Ein override macht man manuell wenn einem die Basisfunktionalität nicht passt oder die Methode als abstrakt markiert wurde. Nicht generell weil's geht...

LG

02.04.2019 - 14:46 Uhr

Hi,

Visual Studio Auto Generate? Kein Plan was das ist - aber: der Hashcode eines Objektes soll sich nicht ändern, was auch immer das generiert hat - ignoriert diese Regel - mit entsprechenden Folgen.

Auf der anderen Seite: Warum GetHashCode() überschreiben, wenns ohne perfekt funktioniert? Mir fällt hierzu in deinem Fall kein Grund ein. Also einfach das override löschen.
(Gründe das zu überschreiben sind ohnehin eher rar gesät...)

18.03.2019 - 16:01 Uhr

Hi,

für mich geht das Problem leider nicht klar hervor.

Grundsätzlich sieht es so aus, als ob du alles zeilenweise einliest und verarbeitest - das ist ja ok so.

Somit kannst du problemlos im Rahmen einer If-Bedingungen mit string.StartsWith prüfen, ob die Ziele entsprechend anfängt und nur in diesem Fall etwas mit string.Replace ersetzen.

Falls diese if-Bedingung unübersichtlich wird kann ich dir persönlich nur empfehlen dich mit "Regex" auseinanderzusetzen. Ist ein recht abstraktes System zur Analyse und ggf. Ersetzung von Strings, dass dir hier sicher gute Dienste leisten würde. (Da wird ne halbe Stunde dich nicht zum Meister machen - aber es lohnt sich da etwas Arbeit reinzustecken)

LG

18.03.2019 - 10:33 Uhr

Hi,

naja - wie auch immer du Zugriff auf Form1 bekommst - unter Form1.Controls stehen sicher auch deine Panels.

ABER: Was immer du da tust - lass es besser - an der UI einer anderen Form sollte man nicht direkt rumpfuschen - sondern viel eher eine entsprechende Schnittstelle anbieten, die dieses Handling steuert.

LG

14.03.2019 - 11:00 Uhr

@Palladin: XPath verwendet man ja auch beim HtmlAgilityPack - nur, dass hier teils schon automatische Fehlerkorrektur eingebaut ist soweit möglich.

@TE:
Ich weiß zwar nicht woran du gescheitert bist - aber ich behaupte es wäre mit dem AgilityPack einfacher. Dein HTML sieht valide aus - und mal als Beispielcode um die Texte der letzten TD-Tabelle anzuzeigen würde mal folgendermaßen vorgehen:


static void Main()
        {
            var path = @"C:\test.html";
		
            var doc = new HtmlDocument();
            doc.Load(path);

            var tdNodes = doc.DocumentNode.SelectNodes("/html[1]/body[1]/table[1]/tr[3]/td[1]/table[1]/tbody[1]/tr[1]/td");
            var values = tdNodes.Select(node => node.InnerText);
            foreach(var value in values)
                Console.WriteLine(value);
            Console.ReadLine();
        }

LG

PS: Den XPath den ich dort verwendet habe gibt dir HtmlAgilityPack schon im Debugger beim Durchnavigieren.

PPS: Da ich davon ausgehe, dass du nicht an den Überschriften interessiert bist habe ich dein HTML-Beispiel für meinen Code so erweitert, dass eben noch die wirklich interessante Tabelle mit irgendwelche Werten drin steht.

14.03.2019 - 10:30 Uhr

Hi,

ich kann dir nur abraten zu versuchen selbst HTML zu parsen. Das fehlerfrei zu bauen erfordert deutlich mehr Aufwand als schlicht ein Paket zu verwenden, dass das schon längst kann.

Schau dir mal https://html-agility-pack.net/ an - versuch's damit aufzubauen - und wenn da was schief geht: Weiter fragen.

LG

PS: Dein hier gezeigter Teil vom HTML ist ungültig. HTML-Tags gibt's eigentlich nur folgendermaßen:
<td**>**MyText</td>
(Der fett markierte Teil fehlt bei dir, wenn das so ist - hilft dir vermutlich auch das AgilityPack nicht mehr...)

12.03.2019 - 15:37 Uhr

Hi,

@Abt - ich glaube LiMuBai meinte etwas anderes - quasi eine Id für eine Zeitzone in der Datenbank hinterlegen.

Wurde auf StockOverflow schonmal erfragt:
https://stackoverflow.com/questions/11580423/what-is-the-best-way-to-store-timezone-information-in-my-db

Kurzform: TimeZoneInfo.Id pro Maschine in der Datenbank hinterlegen. Die eigentlichen Zeiten in UTC speichern - und nur zur Anzeige mit Hilfe von http://msdn.microsoft.com/en-us/library/system.timezoneinfo.findsystemtimezonebyid.aspx in die "Maschinen"-Zeit umrechnen.

LG

08.03.2019 - 11:41 Uhr

Hi,

das bedeutet im Prinzip, dass in jeder Instanz der Klasse in der diese Definition steht beim Zugriff auf die Eigenschaft "Kadett" die gleiche Referenz verwendet wird.

Wenn du also 2 Instanzen der Klasse hast und in einer der Instanzen an der Variable "Kadett" rumspielst - ändert sich das für alle anderen Klassen ebenfalls, weil überall dieselbe Instanz von Kadett verwendet wird.

LG

PS: Das Wort "überall" ist bei static nicht immer wirklich überall... Das nur als Vorwarnung.

04.03.2019 - 17:23 Uhr

Hi,

das Lesen einer Textdatei hatte ich bereits oben verlinkt - ab davon wäre das eine Google-Suche wert. (Wieso Google-Suche? Es gibt viele verschiedene Methoden eine Textdatei zu lesen, am Stück, Zeilenweise, Zeilenweise, ggf. sogar asynchron..., da wirst du dir Gedanken machen müssen, wie du das gerne angehen möchtest bzw. wie groß die von dir unterstützten Textdateien sein dürfen ohne dass dein Programm hängt)

Was den Beispielcode angeht:
Diese Methode wurde dort nicht veröffentlicht und würde dir auch nichts helfen - du willst ja einen barrierefreien Texteditor - keine simple Textbox. Also wirst du da viele Sachen selbst machen müssen.

LG

04.03.2019 - 16:25 Uhr

Hi,

führt er denn die Methode aus? (Debugger benutzen)

Meine nächste Vermutung wäre, dass dein Argument wegen fehlender Anführungszeichen gesplittet wurden und somit deine Überprüfung auf Arguments.Count == 1 scheitert.

LG

PS: Eine Bitte - Benutz doch auch mal einen Punkt - ich fühl mich mit Ausrufezeichen immer angeschrien 😉

04.03.2019 - 16:04 Uhr

Hi,

ok - der Fehler warum keine MessageBox kam liegt in der App.xaml.cs.

Du definierst aktuell:
a) Einen StartupPath
b) Eine StartupURI

Da die StartupURI Vorrang hat - wird dein StartupPath ignoriert.
-> Entferne die StartupURI

Lesen einer Textdatei:
https://docs.microsoft.com/de-de/dotnet/csharp/programming-guide/file-system/how-to-read-a-text-file-one-line-at-a-time

LG

04.03.2019 - 15:55 Uhr

Hi,

du hast doch überhaupt nichts geschrieben (in deinem Code), dass eine Textdatei geöffnet werden soll... Lediglich eine MessageBox, die sagt, dass du das tust.

Kam diese wenigst?

04.03.2019 - 13:21 Uhr

@marlem:
Für eine solche Antwort hättest du deine Frage deutlicher formulieren müssen.

Keiner hier hat erwartet, dass du in der Lage bist einen barrierefreien Texteditor zu basteln - jedoch noch nie die Argumente einer Anwendung beim Programmstart benötigt hast...
(Zugegeben - bei WPF geht's ein wenig anders...)

Der Link zum richtigen Tutorial: https://www.wpf-tutorial.com/wpf-application/command-line-parameters/

LG

Edit:
Abgesehen von der Großschreibung könnte man deinen Beispielcode übrigens 1:1 in Windows-Forms und Konsolenanwendungen verwenden 😉

04.03.2019 - 12:57 Uhr

Abt,
nach Löschung des Programms verbleiben dabei Registry-Einträge die ab diesem Zeitpunkt als Müll zu betrachten sind - es sei denn Windows würde das aufräumen - was ich allerdings bezweifle.

Wenn das im Programm selbst gemacht wird - hat man ja quasi keine Chance mehr aufzuräumen - im Installer allerdings durchaus.

LG

04.03.2019 - 12:42 Uhr

Hi,

noch als Anmerkung:
Eine solche Programmfunktion ist in meinen Augen etwas, das ausschließlich einem Installer beigebracht werden sollte.

Ansonsten hinterlässt du Müll wenn dein Programm entfernt wird...

LG

27.02.2019 - 16:14 Uhr

Hi,

eine while-Schleife ist schon korrekt. Do-While wäre in deinem Fall wohl die einfachste Variante.

Grundsätzlich kommt um deinen aktuellen Code der "do"-Teil drumherum, das Ergebnis deiner If-Anfrage müsstest dir zu Beginn des "do"-Teils merken und dann am Ende im "while"-Teil prüfen.

Ein Beispiel siehst du z.B. auf:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d3243923-0802-454a-bd15-2d80ed860705/how-to-repeat-question-if-user-input-is-invalid-c?forum=csharpgeneral

LG

26.02.2019 - 14:41 Uhr

Hi,

ohne auf den Logger einzugehen (da solltest du dich wirklich mal in die gängige Praxis einlesen) bräuchtest du etwa folgendes:


var result = Task.FromResult(new HelloReply { Directrories = new DirectoryInfo(request.Path).FullName });
logger.Log(...);
return result;

LG

25.02.2019 - 16:21 Uhr

Hi,

grundlegend: Wenn du keinen Input brauchst - braucht deine Methode auch kein JSON/Input - also geht eine Methode à la:


public IActionResult DoYourThing()
{
// do your thing
return Ok();
}

Allerdings musst du aufpassen - WebRequests haben ein Timeout - wenn du dieses nicht beachtest - bricht dir sowas auch leicht mal ab - falls das ein Problem ist - solltest du dir mal folgendes anschauen:
https://blogs.msdn.microsoft.com/cesardelatorre/2017/11/18/implementing-background-tasks-in-microservices-with-ihostedservice-and-the-backgroundservice-class-net-core-2-x/

Alternativ kann man auch die Timeouts anpassen, siehe:
https://stackoverflow.com/questions/37474309/timeouts-with-long-running-asp-net-mvc-core-controller-httppost-method

LG

21.02.2019 - 11:46 Uhr

Hi,

ich glaube du hast hier einen nicht ganz so schlauen Ansatz mit Textdatei pro Datensatz.
(Wahnsinnig ineffektiv, sofern dein Spiel jemals ernsthaft benutzt würde und einige Dateien zusammenkommen)

Was hindert dich denn daran alle Datensätze in einer Datei abzuspeichern?
(Hier solltest du dich auch mal dringend in folgende Themen einlesen:
a) XML
b) JSON
c) Serialisierung
-> Das wird dir potenziell extrem viel Code sparen)

Praktisch musst du ohnehin alle Datensätze lesen, sortieren, und dann die besten rauspicken und anzeigen - es sei denn du speicherst diese in einer Datei jeweils vorsortiert...

Falls du da auf bestimmte Probleme triffst - am besten einen neuen Thread erstellen.

LG

18.02.2019 - 07:04 Uhr

Hi,

hab bei uns etwas ähnliches machen müssen - allerdings in kleinerem Maßstab, da ein Teil der Daten vollautomatisch aufbereitet werden konnte.

Die Reihenfolge
Um ehrlich zu sein weiß ich nicht, wie die Aufbereitung der Daten die Reihenfolge ändern sollte - kann ich somit nichts zu sagen.

Ich für meinen Teil habe unaufbereitete Daten in einer anderen Tabelle wie aufbereitete Daten gesammelt - aber einen Unterschied macht das praktisch nicht. Die Datensätze brauchen jedenfalls:

  1. Ein Feld, in dem der Mitarbeiter, der diese aufbereiten soll bzw. seine ID eingetragen wird
  2. Ein Feld, wann der Mitarbeiter sich den Datensatz "geschnappt" / "gesperrt" hat
  3. Bei dir dann noch ein Feld in dem steht ob die Daten schon aufbereitet wurden

Im Programm würde ich eine Wizard-ähnliche Struktur vorhalten, die dem User schön sauber je einen Datensatz präsentiert. Bei mir ist es so gemacht, dass sich das Programm bei jedem Click auf "Weiter" einen neuen Datensatz und RestCounter (Motivation^^) holt und den Datensatz in der DB jeweils mit User + Zeitstempel sperrt. Vom SQL-Zugriff entfernt man dann erst alle abgelaufenen Logs - und holt sich dann den ersten Datensatz ohne Sperrung. (Die Sperrung sollte auch eine überzogene Mittagspause aushalten)

LG

14.02.2019 - 14:15 Uhr

Hi,

der Hinweis von Abt ist durchaus eine Antwort - es hätte sich gelohnt hier mal nachzuschauen.

Du hast eine weiße Seite - schön und gut - es gilt es herauszufinden was das Problem ist - dafür wäre zumindest mal der Netzwerkverkehr als nützliches Hintergrundwissen erforderlich, da man dich andernfalls lediglich zu deiner weißen Seite "beglückwünschen" kann.

Was den Server selbst angeht (shadowcmd.ch) - ich bekomme den Server zwar aufgelöst - eine Antwort schickt dieser mir jedoch nicht. Vorausgesetzt da läuft überhaupt ein http/https-Server - würde ich mal prüfen, ob dort vll nur ganz bestimmte Netze/Adressen durchkommen.

LG

12.02.2019 - 06:59 Uhr

Hi,

naja - ich gehe davon aus, dass er gar nicht bis zu deinem Logging kommt - was sagt denn das Windows-Ereignis-Protokoll? Alternativ - mir hat's auch schon mal geholfen einfach "dotnet run" auf dem Server auszuführen - da war er teils deutlich gesprächiger... Mit den beiden Mitteln solltest du jedenfalls deutlich mehr als einen Netzwerkfehler haben...

LG

07.02.2019 - 10:50 Uhr

Hi,

hm - da fehlt es scheinbar an mehr als ASP.NET-Wissen.

Grundlegend solltest du versuchen:
a) Eine 3-Schichten-Architektur aufzubauen, siehe [Artikel] Drei-Schichten-Architektur
b) Ich hoffe deine Datenbankschnittstelle sieht nicht wirklich so aus wie gezeigt, falls dem doch der Fall ist solltest du dir dringend folgende Sachen anschauen:

  1. Wieso static (meistens) doof ist: https://stackoverflow.com/questions/241339/when-to-use-static-classes-in-c-sharp
  2. UnitOfWork-Pattern (-> Sammlung von Aktionen für Datenbanktransaktionen)
  3. RepositoryPattern (-> gute Abstraktion zur Kommunikation mit der DB)
    c)ASP.NET (du schreibst leider nicht welche Version du verwendest) unterstützt in aktuellen Versionen "DependencyInjection" - in Zusammenarbeit mit den im Voraus genannten Stichpunkten kann mit Hilfe von DependencyInjection im Konstruktor der Klasse ein entsprechender Service injiziert werden, mit dem der/die Controller dann arbeiten können.

Mal als Beispiel wie sowas grob aussehen kann ein Projekt von Abt, wo man sich einiges abschauen kann ohne dass es all zu unübersichtlich wird:
IdentityServer4 Plattform Beispiel basierend auf .NET Core und ASP.NET Core

LG und Viel Erfolg

06.02.2019 - 11:57 Uhr

Hi,

ich verstehe das Problem auch nicht.

Die eigentliche Arbeit des BackgroundWorkers passiert ja ohnehin im DoWork, in welchem ja offensichtlich der String schon vorhanden ist.

Wo ist das Problem diesen String dann entsprechend auszugeben?

Ein Beispiel dazu findest du z.B. unter https://stackoverflow.com/questions/1862590/how-to-update-gui-with-backgroundworker

LG