Wie Pippl ja bereits geschrieben hat ist HTL-Abschluss bei weitem kein Studium. Man hat einen Abschluss der einen berechtigt weiter zu studieren an zb einer Uni/FH. Je nach Richtung der HTL und danach gewähltem Studium ist es möglich sich 1-2 Semester anrechnen zu lassen.
Wenn ich das jetzt mit deutschen Verhältnissen vergleichen müsste dann würde ich sagen dass ein HTL-Abschluss + anschließendem Ingeneurstitel ungefähr dem Stand eines Fachinformatikers entspricht.
Trotzdem solltest du nicht mehrere Foren gleichzeitig "belästigen". siehe [Hinweis] Wie poste ich richtig? 2.2
Crosspost
Ich schätze mal du verwendest OleDb um darauf zuzugreifen?
Falls dem so ist kannst du OleDbConnection.GetOleDbSchemaTable() verwenden.
Ich teste das morgen auf der Arbeit. Hab grad keinen MAC zur Hand.
Aber soweit ich mich erinnern kann musste ich keine Leerzeilen bzw Kommentare entfernen.
EDIT: Ich habe das Script eben getestet und das mit den Leerzeilen und Kommentaren funktioniert problemlos wenn ich eben npsvosx.exe durch meine ersetze.
Das Einzige was mir aufgefallen ist bzw ich geändert habe:
EXE_PATH="$DIR\npsvosx.exe"
Versuch mal einen Slash(/) anstatt des Backslash zu verwenden.
Auf welchem OSX hast du das getestet?
Hast du das Script vorher auch auf executeable gesetzt? chmod +x
Also ich habe vor einiger Zeit selbst ein erweitertes Shell-Script, das uA gleich das Mono-FW lädt und installiert, auf Basis dieses Posts gebastelt.
Starte das Shell-Script mal im Terminal und poste die Ausgabe bzw poste mal dein Shell-Script.
Warum Leute die mit Computer arbeiten so viel Zeit haben:
Mittels XmlDocument.Load() kannst du dir den Umweg über den WebClient sparen.
So ich habe mich jetzt mal eingehend mit dem Problem beschäftigt und etliche Tests durchgeführt.
Der csv Reader ist nicht das Problem. Das Einlesen dauert ca. 3-4 Min.
Danach habe ich versucht eben nicht nach jeder gelesenen Zeile eine Anfrage an die DB zu senden sondern eben alles einzulesen und dann nur 1 Anfrage zu stellen. In der csv stehen ca 40000 verschiedene Tracks. Dies brachte auch nicht so wirklich einen Zeitsprung. Das wurde dadurch nur 30 Minuten schneller.
Als letzte Lösung habe ich dann versucht mal nHibernate ganz wegzulassen und direkt ein DataTable zu verwenden. Bis das DataTable mit den 40000 Zeilen/Tracks geladen ist dauert es ca 30 sec.
Heureka ich dachte jetzt hab ichs. Auslesen der csv in ein DataTable 3 Min + laden der 40000 Tracks in eine DataTable weitere 30 sec. Einfach nur die fehlenden Infos aus der Datatable holen und in der anderen ergänzen. Mittels Linq ja auch einfach und schnell erledigt. Das sollte nicht lange dauern und definitiv etwas bringen.
Dann auch gleich getestet und es kam die böse Überraschung. Das ganze dauert immer noch 6 Stunden. Somit hab ich fast nix gewonnen.
Nur wie kann das sein? Ich hab beide DataTable im Speicher und durchlaufe die mit 2 verschachtelte foreach Schleifen.
Hier der Code: Bis der durchgelaufen ist dauert es eben 6 Stunden.
foreach (DataRow row in dtTracks.Rows)
{
DataRow row1 = row;
var rows = dtSales.AsEnumerable().Where(r => r["isrc"].Equals(row1["isrc"]));
foreach (var row2 in rows)
{
row2["artist"] = row["artist"];
row2["title"] = row["title"];
row2["labelcode"] = row["labelcode"];
row2["cline"] = row["cline"];
row2["duration"] = row["duration"];
}
}
dtTracks ist mein DataTable mit den 40000 Tracks/Zeilen.
dtSales ist das riesige Datatable mit den den Werten aus der csv.
Was kann ich noch machen? Ich bin grad mit meinem Latein am Ende und für weitere Ideen mehr als dankbar.
Parallel.Foreach würde mir noch einfallen. Nur kann ich darauf nicht zugreifen, da ich aufs 3.5er FW zugreifen muss. Außerdem kann ich mir net vorstellen dass ich damit von 6 Stunden auf 1 runter komme.
Super, vielen Dank.
Das bringt mich schon ein ganzes Stück weiter.
Noch ein wenig zum Hintergrund.
Wie gesagt handelt es sich hierbei um Verkaufszahlen. Wir bekommen derzeit ca 50 verschiedene csv/txt Dateien in unterschiedlichen Formaten(andere Header, Trennzeichen, etc) und einigen Eigenheiten. Nicht alle sind immer well-formed. Darum auch der Reader und nicht nur ein einfacher StreamReader.
Der Reader liest jetzt eben abhängig vom File die jeweiligen Werte, die benötigt werden, raus(Dazu unten mehr). Als Identifier dient hier der EAN/ISRC(falls sich jemand ein wenig im Msuic-Business auskennt) und anhand dessen Stelle ich die Abfrage via nHibernate an die DB um das Album zu erhalten, denn anhand der Trackanzahl und Spieldauer der jeweiligen Tracks werden dann eben die Berechnungen durchgeführt.
Sprich hier brauch ich sowieso immer gleich die Tracks dazu, also eager loading. 15mio Anfragen kommen hier nicht zustande, da viele Zeilen im CSV ident sind.
Also in der csv steht in Zeile 1: Album A hat sich in Deutschland 100 mal verkauft => Anfrage via nHibernate an die DB um welches Album es sich handelt
Zeile 2: Album A hat sich in Österreich 50 mal verkauft => keine Anfrage an DB, da ich das Album bereits in meinem Dictionary hab.
Zeile 3: Album B ... => Anfrage an DB
Unsere Tabelle mit den Alben/Tracks umfasst ca 500.000/5.000.000. Somit können derzeit nur max 500.000 Anfrage während des Auslens der CSV an die DB gestellt werden. Wie gesagt wächst die natürlich auch kontinuierlich. Darum will/wollte ich die nicht einfach vorab laden sondern eben nur pro Zeile bzw die Alben/ Tracks die auch verkauft wurden. Sonst hätte ich 5,5 Mio Objekte im Speicher und verkauft wurden dann aber nur 1000 unterschiedliche.
Hier werde ich mich mal mit dem nhibernate Profile einklinken und gucken was da wirklich so abgeht.
Caching
Das mit dem Clear passiert noch nicht. Das werde ich auch mal testen und etwas rumspielen.
Cascade
Mapping werde ich auch nochmals prüfen. Mit nHibernate lade ich eben nur die Informationen zu den jeweiligen Tracks/Alben. Ich führe nur Selects keine Insert/Update/Delete aus.
Wie oben erwähnt brauch ich aber sowieso alle Tracks des Albums.
Die Daten werden in eine andere Tabelle geschrieben.
Mein Datatable hat eigentlich nur folgende Spalten:
EAN: der wird aus der csv
ISRC: ebenfalls csv
Stückzahl: ebenfalls csv
AlbumTitel: kommt eben via nhibernate-Abfrage
TrackTitel: ebenfalls nhibernate
Label: ebenfalls nhibernate
und dann eben noch 3 double-Spalten: das sind die Werte die ich berechne
Deswegen verwende ich eben ein Datatable das ich zur Hälfte mit Daten aus der CSV und zur anderen Hälfte mit den Album- und Track-Informationen und meinen Berechnungen befülle.
Das schien mir in meinem Fall am performantesten. Spricht etwas gegen dieses Vorgehen?
Ich werde auch mal nen Vergleich zwischen meinem CSV-Reader und dem FileHelpers machen.
Werde in den nächsten Tage etliches rumtesten und versuchen nen genaueren Überblick zu geben bzw Ergebnisse zu posten.
Also ich wäre definitiv an einem Artikel zu Optimierungen von nHibernate.
PS: Heute hab ich mal nur getestet wie schnelle es der Import-Assistent aus dem SQl Management Studio schafft die 900MB und 15Mio Zeilen in die Tabelle zu packen. Das war in ca 3-4 Minuten erledigt. Wie gesagt nur die reinen Daten aus dem CSV. Keine zusätzlichen Infos und Berechnungen.
Leider hat sich mittlerweile beim Auslesen einer riseigen csv Datei und anschließendem speichern in die DB ein Performanceproblem ergeben.
Die csv ist derzeit ca 1GB groß mit ca 15.000.000 Zeilen und wird vermutlich auch in nächster Zeit noch wachsen.
Ein wenig zum Hintergrund wie und was derzeit passiert.
In diesem CSV stehen pro Monat die Verkäufe von Alben bzw Tracks nach Länder aufgeschlüsselt.
1.)Die Csv wird derzeit mit folgendem Reader zeilenweise ausgelesen.
2.)Dann wird eine Anfrage an DB geschickt und das Album bzw der Track geladen, der diesem Verkauf entspricht. Dies erfolgt via nHibernate und es wird immer das gesamte Album inkl Tracks geladen, da die später für Berechnungen gebraucht werden.
3.) das Ergebnis der DB Abfrage wird in einem Dictionary gespeichert. Somit wird für alle weiteren Zeilen der CSV geprüft ob das Album/Track schon mal geladen wurde und falls ja eben keine Anfrage an die DB geschickt.
4.) Nun werden eben Berechungen(nur ein paar Subtraktionen und Multiplikationen) mit den Verkäufen und den Album/Tracks gemacht und danach eine Zeile in eine DataTable geschrieben.
5.) Diese Datatable wird dann mittels SqlBulkCopy in eine Tabelle geschrieben. Das Ganze muss innerhalb einer Transaction laufen und deswegen verwende ich eben UseInternalTransaction und BatchSize ist 0.
Bis das Ganze durchgelaufen ist vergehen ca 7 - 9 Stunden. Wobei die Schritte 1-4 ca zwei Drittel der Zeit in Anspruch nehmen.
Jetzt kam die Anforderung, dass dies(csv auslesen und in db speichern) schneller gehen muss. Das muss in 20 Minuten erledigt sein. Persönlich halte ich das für mehr als utopisch aber evtl lässt sich ja doch was machen.
Was mir noch aufgefallen ist, dass das abschließende Commit so lange dauert wie das schreiben in die DB. Ich lasse mich mittels NotifyAfter alle 10% vom Fortsschritt informieren. Dieser steht nach 1 - 1,5 Stunden bei der Anzahl der Rows und das abschließende Commit verbraucht wieder so ca 1 Stunde.
So und nun zu meinen Fragen:
Wo bzw wie könnte man noch optimieren?
Ich habe bisher noch nie mit so riesigen Datenmengen gearbeitet. Evtl ist die Dauer ja normal?
Ich könnte vorher bereits alle Alben/Tracks aus der DB laden. Somit enfällt dann der DB-Zugriff während des csv-auslesens. Das würde evtl etwas bringen nur werden die Alben/Tracks täglich mehr und irgendwann entsteht vermutlich hier der Bottleneck.
Die Csv in kleinere Portionen aufteilen und jeweils in die DB schreiben. Nur muss ich mich dann ja selbst darum kümmern falls zb beim letzten Batch was schief läuft, dass alle vorherigen auch gelöscht werden.
Muss es unbedingt Regex sein?
Ansonsten könntest du im TextChanged-Event folgendes machen:
textBox.Text = textBox.Text.ToUpper();
mdProjectTimer dürfte so ziemlich das sein was du suchst. Du kannst hier deine Projekte verwalten/anlegen und dann einfach mittels Mausklick wechseln und am Ende siehst du dann welches Project etc wie viel Zeit in Anspruch genommen hat.
Sry für Offtopic. Ja Regex sind ein echt mächtiges Werkzeug. Ich hab leider auch viel zu spät angefangen Sie zu nutzen.
Aber dazu fällt mir noch ein Jamie Zawinski Zitat ein:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
Was leider auch häufig zutrifft.
var lines = File.ReadLines("myFile.txt").Where(s => !s.StartsWith("#"));
Das gibts schon fertig im FW und nennt sich Serialisierung. Da kannst du eine der Arten nehmen zb Binär oder eben auch Xml.
Crosspost
Sieh dir mal [Hinweis] Wie poste ich richtig? 2.2 an.
Mir würden da spontan Pipes einfallen?
Das nenn ich mal nen WTF-Konstrukt:
void marker(string WORT, RichTextBox textBoxName, Color farbe)
{
int index = 0;
found = false;
do
{
try { index = textBoxName.Text.IndexOf(WORT, index); }
catch { }
if (index >= 0)
{
textBoxName.SelectionStart = index;
textBoxName.SelectionLength = WORT.Length;
textBoxName.SelectionColor = farbe;
index += WORT.Length;
}
else break;
}
while (found = true);
}
Ich bin einfach nicht auf die Idee gekommen den Wert + die Anzahl der nachfolgenden Leerzeichen für den einzufügenden Text zu ersetzen.
Also so wie in dem Bsp von DerKleineTomy.
Somit hab ich jetzt eine allgemein gültige Lösung. Ich habe nämlich verschiedene Frames bzw Templates. So wie BerndFfm das gezeigt hat hätte ich dann für jedes Template ne eigene Behandlung machen müssen.
Vielen Dank, also so einfach kanns gehen.
Ich glaub ich steh grad am Schlauch. Wie soll mir das helfen?
da müsste ich ja wissen wie viele Zeichen es bis zum Rand sind und womit soll ich den string auffüllen? Es verschiebt mir ja dann trotzdem wieder den rechten Rand.
Hi
Also ich habe eine vorgegebene txt-Datei und in diese soll ich Werte aus einige TextBoxen schreiben.
An sich keine Problem, dachte ich mir. Machst du dir einfach ein paar Placeholder rein und dann mittels Replace die Werte ersetzen. Nur so einfach ist das leider nicht, da es mir dann das Layout der txt-Datei zerstört.
Damit ihr seht wie ich das meine:
[pre]
_|______________________________|_
| |
| Wert1: |
| Wert2: |
| Wert3: |
| Wert4: |
_|______________________________|_
[/pre]
Wenn ich da jetzt die Werte einfüge verrutscht mir natürlich rechts der ganze Rand.
Kennt ihr evtl einen Weg wie ich das anstellen könnte ohne das es das Layout zerstört? Mir will da grad nicht wirklich ne zündende Idee kommen.
Steht eigentlich drin was du tun musst:
Anonymous type members must be declared with a member assignment
Also folgendes:
select new
{
o.OrderId,
o.OrderDate,
Foo = o.ShippingAddress + o.ShippingCity, //So klappt das
o.ShippingCountry,
o.ShippingZipCode
};
Du versuchst E-Mails via Hotmail zu versenden. Das hatten wir schon mal: E-Mails via Hotmail senden
So wie es aussieht verwndest du den falschen Port.
Ja das sollte möglich sein. Allerdings funktioniert dann Lazy-Loading nicht mehr.
In Fluent nHibernate musst du dann folgendes angeben:
Not.LazyLoad();
Fürs klassische nHibernate Mapping wäre es im XML so:
<class name="Class" table="Table" lazy="false">
Ich verwende nHibernate in Kombination mit Fluent nHibernate. Damit geht das ganze eigentlich ratz-fatz.
Und die Config für nHibernate ist ja auch schnell erledigt. Dazu gibts auf der Homepage ein Tutorial.
Kommt ein OR-Mapper(zb nHibernate) in Frage? Da stellst du es in der Konfig ein welcher Dialekt verwendet wird und den Rest übernimmt nHibernate für dich.
Wäre es nicht am einfachsten den Task im Kontext des Benutzers laufen zu lassen der auf die Freigabe zugriff hat? Und auf diese eben nicht über das Netzlaufwerk zuzugreifen sondern eben über den UNC-Pfad.
Hab heute in unserem Code vermehrt folgendes Konstrukt vorgefunden:
title = title.TrimStart(' ').TrimEnd(' ');
Moin,
Ich habe in meinem Projekt laut Resharper 2 Error und zwar meckert er bei BeginInvoke bzw EndInvoke an dass: > Fehlermeldung:
Argument is 'out' while Parameter is declared as 'value'
Das ganze sieht folgendermaßen aus:
der Delegate:
private delegate int Foo(out string name);
Der Aufruf:
string s;
Foo f = Bar;
IAsyncResult ia = f.BeginInvoke(out s, null, null);
int i = f.EndInvoke(out s, ia);
Bei dem besagten out s kommt eben der Error von Resharper. Wenn ich jetzt sage Correct argument kind, dann lässt er das out weg. Dann kompiliert es nicht mehr was ja auch klar ist, da dass Argument mit out übergeben werden muss.
Nur was genau is das jetzt das Problem bzw was meckert Resharper hier an. Ist das ein Fehler oder ein Bug im Resharper?
Evtl is es ja auch noch zu Früh und ich üebrseh da ja etwas.
Crosspost
siehe [Hinweis] Wie poste ich richtig? 2.2
Das kann man verkürzen bzw müsste man die Controls rekursiv duchgehen:
Controls.OfType<PictureBox>();
Aber wie wäre es mit folgendem Ansatz:
private void pictureBox1_Click(object sender, EventArgs e)
{
Controls.OfType<PictureBox>();
Control ctrl = sender as Control;
if (ctrl != null)
DoSomething(ctrl);
}
private void DoSomething(Control ctrl)
{
ctrl.BackColor = Color.Red;
}
Sorry ich war die letzten Wochen in Urlaub und konnte mich dem Problem erst jetzt wieder widmen.
Code ist folgender:
SmtpClient smtpClient = new SmtpClient(ConfigurationManager.AppSettings["exchangeServer"]);
smtpClient.UseDefaultCredentials = true;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.SendCompleted += smtpClient_SendCompleted;
MailMessage mm = new MailMessage(tbFrom.Text, email, tbSubject.Text, rtbBody.Text);
mm.IsBodyHtml = true;
smtpClient.SendAsync(mm, email);
//smtpClient.Send(mm);
Über SendAsync kommt eben folgende Meldung:> Fehlermeldung:
Für den SMTP-Server ist eine sichere Verbindung erforderlich, oder der Client wurde nicht authentifiziert. Die Serverantwort war: 5.7.1 Client was not authenticated
Die normale Send Methode funktioniert mit obigem Code einwandfrei.
Wie gesagt wenn ich statt UseDefaultCredentials eben explizit Credentials setze dann klappts auch mit SendAsync. Nur das will ich vermeiden.
Mit NotifyFilters und hier im Speziellen auf Attributes sollte das möglich sein.
3 Stichwörter: SynchronizationContext, AsyncOperation und AsyncOperationManager
The .NET Framework's New SynchronizationContext Class noch das passende Tut.
Der BackgroundWorker verwendet intern auch diese Methode.
Also ich habe folgendes sehr merkwürde Problem.
Ich verschicke Mails über unseren Exchange. Dieser erfordert eine Authentifizierung. An sich kein Problem ich setze eben UseDefaultCredentials und es funktioniert.
So wenn ich nun die Mail via SendAsync versende kommt jedes Mal die Fehlermeldung das man nicht authentifizeirt ist und man sich eben authentifizieren muss.
Nach dem wtf Moment kam ich auf die Idee mal die Crdentials explizit zu setzen.
Und siehe da dann klappt es auch mit SendAsync().
Gut ich könnte jetzt den Benutzer auffordern sein Benutzername und Passwort einzugeben und verschlüsselt zu speichern. Nur möchte ich das ganze vermeiden bzw ist das imho auch kontraproduktiv, denn wozu gibt es UseDefaultCredentials. Zumal die dann auch noch im Klartext übertragen werden.
Hat jemand ne Idee oder muss man bei SendAsync die Credentials wirklich explizit setzen?
Nur als Tip. Ich würde gleich die Version Klasse verwenden anstatt string.Compare().
Obiger Code-Ausschnitt funktioniert bei mir einwandfrei. Ich habe das mit meinem Hotmail-Account getestet. Allerdings ist hotmail eher suboptimal, da die es dann nicht mehr erlauben Mails zu versenden.
Man erhält dann folgende Benachrichtigung:
Hello xxx xxx,
To continue sending messages, please sign in to your Windows Live Hotmail account (
> ). After you sign in, we'll show you a picture and ask you which letters and numbers you see inside it.This helps us prevent automated programs from sending junk.
Thank you for your help and patience!
Sincerely,
The Hotmail Team
Und ich vermute fast das genau hier dein Problem liegt. Also logge dich mal in deinen Hotmail-Account ein.
Naja in dem andren Thread steht ja schon dass du dich authentifizieren musst.
Also:
SmtpClient smtp = new SmtpClient("smtp.live.com", 587);
smtp.EnableSsl = true;
smtp.Credentials = new NetworkCredential("user", "pw");
smtp.Send("from", "to", "subject", "body");
Crossposts sind ein nogo.
siehe [Hinweis] Wie poste ich richtig? 2.2
Naja es werden sicherlich noch zusätzliche (Header-)Information in den Files stecken. Deshalb funktioniert ein einfach zusammenkopieren auch nicht.
Du solltest mal den Aufbau einer rar-Datei rausfinden und dann eben genau die entsprechenen Infos auslesen, ändern und löschen.
Ja, das ist auch klar. Du verwendest ja keinerlei Transactions.
Somit werden gerade noch Daten in die DB geschrieben und diese Operation ist noch nicht mal fertig und gleichzeitig werden sie schon an andere Stelle wieder gelesen.
Das musst du schon selbst übernehmen, das macht nicht die DB für dich.
Aber such mal nach "MySqlDataAdapter Transaction". Da findest du genug.
Am besten schreibst du dir selber ne (Extension)Method, die die das macht. Das sollte relativ schnell erledigt sein. Als Basis kannst du zb DataTable in CSV Datei speichern nehmen und um deine Anforderungen ergänzen.
Naja nach was hast du gesucht? Wenn man in Google nach "c# read memory" sucht dann kommen haufenweise Treffer.
Unter andrem auch: How to write a Memory Scanner using C#
Also ich hab mit dem C Sharp Ripper gute Erfahrungen gemacht. Einzig bei mixed CDs(also Audio- mit Daten-Tracks) hat er manchmal etwas rumgezickt.
Such mal im Google nach "fritzbox reconnect.bat". Da findest du dann genügend wie das geht. Falls es unbedingt C# sein soll dann kannst du den Code ja leicht portieren.
Ansonsten gibts zb auch gleich ein FireFox-Addon dafür.
Da ich heute nen guten Tag habe hab ich mal ein kleines Demo Projekt gemacht.
Es liest den aktuellen Eintrag aus dem XML aus. Erhöht dann den Count und speichert es wieder ab bzw erzeugt ein neues Node falls noch keines vorhanden ist.
Kannst du mal das komplette Projekt anhängen. In diesem fehlen einige Dateien.
Muss es denn unbedingt Regex sein? Ich bin jetzt auch nicht so der Regex Profi, aber wenn ich nicht auf das betreffende Pattern komme dann müssen eben mal die String-Operationen herhalten.
Also in deinem Bsp dann so:
const string searchPattern = "FBA-";
string[] toSearch = {"12345", "FBA-12345", "FBA-FBA-12345", "FBA-FBA-FBA-12345", "FBA-F-12345"};
foreach (var s in toSearch)
{
int index = s.LastIndexOf(searchPattern, StringComparison.Ordinal);
string result = index == -1 ? s : s.Substring(index + searchPattern.Length);
Console.WriteLine(result);
}
Nimm den WebClient mit HTTP-POST- und Cookie-Unterstützung und dann einfach folgendes:
ExtendedWebClient extendedWebClient = new ExtendedWebClient();
// Anmelden per POST; anonymer Typ als Parameterobjekt
extendedWebClient.Post("http://www.example.com/login.php",new
{
LOGON_USERID = "XXXXXX",
LOGON_PASSWD = "XXXXXX"
});
EDIT: Sowas findest du ganz leicht mittels TamperData oder HttpLiveHeaders raus welche Paramter übergeben werden. Sind beides Firefox Plugins.