Laden...

Forenbeiträge von Xynratron Ingesamt 1.177 Beiträge

22.09.2014 - 22:11 Uhr

Hmm, schreiben hilft manchmal:

"Code ist gekürzt und anonymisiert."

Regel 1: keinen Code aus "nettigkeit" wegkürzen, nur weil man denkt, da gibt's keinen Fehler.

"load from DB"

Wenn die DB jetzt in einen Lock fährt - aus welchen Gründen auch immer - ist das Verhalten des Codes außenrum nicht mehr definiert. Wir hatten genau das gleichzeitig auf der DB. Also hat der Code zwar macken, war aber nicht schuld.

Ich hoffe das dient wenigstens als gutes Beispiel für schlechtes Fragen nach Hilfe bei einem Fehler...

😃

Alchemy

22.09.2014 - 22:06 Uhr

Hallo zusammen,

hab mich hier lange nicht gemeldet, aber jetzt ein Problem, dass ich logisch nicht erklären kann:

Der Code ist ~4 Jahre alt und benutzt ein Dictionary für ein internes Caching.


private static Dictionary<int, Tuple<DateTime, object>> myDict = new ..

void foo(key int)
{
  if (myDict .ContainsKey(key))
  {
    var result = myDict[key];
    if ((DateTime.Now - result.Item1) > TimeSpan.FromMinutes(5)) //5 Minutes Cache
      {
        myDict.Remove(key);
      }
      else
      {
        return result.Item2;
      }
    }
  [..] load from DB

  if (myDict .ContainsKey(key))
    myDict[key] = new Tuple<DateTime,object>(DateTime.Now, data);
  else
     myDict.Add(key, new Tuple<DateTime, object>(DateTime.Now, data));
  return data;
}


Code ist gekürzt und anonymisiert.

Das ganze ist nicht durch ein lock geschützt, noch wird z.B. ein ConcurrentDictionary verwendet. Wie gesagt, alter, funktionierender Code.

Meine Frage ist also - außer dass das jetzt etwas korrigiert wird - was sorgt dafür, dass das ganze nicht nur manchmal wegen einem threading Problem (in der Routine) auf die Schnauze fällt, sondern mehrere Stunden eine IndexOutOfRangeException beim Insert (Add) in das Dictionary erzeugt?

Threading-Problem hat das ganze sicher. Ein static überlebt keinen Prozesswechsel (AppPool Recycle)

Ich steh gerade auf dem Schlauch...

😃

Xynratron

22.09.2014 - 21:26 Uhr

Hi zusammen,

Wie wäre es mit:

* Stage und Prod haben dieselben Bindings, aber terminiert auf unterschiedliche IP'S
* Stage und Prod benutzen dieselbe Session & DB
* IP's im LB sind je nach Anwendung getrennt
* Im LB von Prod auf Stage (rein Server basierend, auf IP) umschalten lassen (und das andere zurück)
* Prod und Stage "logisch" tauschen

Das hängt ein wenig von eurem LB ab. Am einfachsten wäre es wohl, wenn man Regeln für die URL zu den physischen Servern angeben könnte oder wenn ihr mehrere öffentliche IP's habt.

stage.example.com -> 141.1.1.1 -> Real 192.168.1.1
live.example.com -> 141.1.1.2 -> Real 192.168.1.2, Real 192.168.1.3

Dann im LB die Real-Server tauschen (lassen). Die User merken nix, außer die Session wird gekillt.

Ansonsten ist ein Ausfall für die User wohl nicht unbemerkt. Sanft kann man das noch mit einem ändern des DNS auf ne andere LB-IP erledigen, dann wandert die Last je nach TTL.

Macht ihr den Umstieg programmatisch über System.Web.Administration oder so? (die 2,3 Sekunden deuten darauf hin)

Ich hab den Thread jetzt nicht ganz nachvollzogen, da ich mit Farmbetrieb weniger Erfahrungen habe, wir regeln alles über LB.

😃

Xynratron

06.04.2012 - 00:26 Uhr

Hiho,

hast du noch ein Backup? DBCC war immer mein Freund in Notfällen. Ehrlicherweise hab ich noch nie eine DB wirklich verloren - es war alles immer irgendwo vorhanden und wiederherstellbar.

Wenn deine DB tatsächlich "eine unerwartet kleine größe" hat, dann sollte man noch nach dem Transaktionslog schauen. Auch sein anzumerken: wenn man in einer 1000Mb Datenbank die Tabellen alle löscht, so hat die DB immernoch 1000 Mb. Der SQL Server gibt nur auf expliziten Befehl (Autoshrink, dbcc) den Speicher an das Betriebssystem zurück. Die änderungen sind wenn dann auch noch im Log, außer es wurde ein komplettes Backup gemacht oder das Log war ausgeschalten (Log = simple).

😃

Xynratron

06.04.2012 - 00:16 Uhr

Hi Ralf,

Hi!
..Windowsstart (also z.b. eine Verknüpfung im Autostartordner) ... dabei scheint der SQLServer-Dienst etwas zu spät verfügbar zu sein, so dass meine Anwendung denk es sein keine Verbindung zum Server möglich.

scheint ja beides auf dem selben Rechner zu liegen. Windows versucht seit geraumer Zeit schneller beim Start zu werden. Der Effekt ist allerdings, dass Windows "schnell" startet, aber die Dienste (mssqlserver) erst später hochfahren. Es sieht schnell aus, aber es läuft noch lange nicht alles. Wenn der Rechner nicht sooo besonders fix ist, dann kann es schon ein paar Minuten dauern. Man merkt das auch gerne daran, dass 2-3 Minuten nach dem Start plötzlich der (endlich gestartete) Virenscanner sich seine Updates holt und nochmal alles ausbremst.

Tips, was man machen kann gabs schon, wollte nur das "Problem" nochmal beleuchten.

😃

Xynratron

06.04.2012 - 00:08 Uhr

Hallo Taladan,

nimm die ganze "schreiben" logik in einen seperaten Thread, dann behält das auch das gewünschte sequenzielle Verhalten.
Im Endeffekt wird nur dein Hauptthread und der 2. Thread vertauscht. Deine Gui im Hauptthread läuft weiter, die Sequenz im Worker bleibt.

😃

Xynratron

11.10.2011 - 00:05 Uhr

huhu,

Je nachdem mit welcher Datenbank und mit welchem Isolationlevel ich arbeite haben die anderen User längere Wartezeiten. Wenn Dirty Reads ausgeschlossen sind müssen die anderen Benutzer warten, bis die Transaktion abgeschlossen sind, bevor sie Daten lesen können. Aus diesem Grunde sind meine Transaktionen immer so kurz wie möglich, maximal so 2 Sekunden.

Handhabe ich genauso. Wenn es wirklich viele Daten sind, dann einzelne Transaktionen a 10.000 Stück (je nach Anwendung variierend) mit einem View zum löschen (der ist tatsächlich performanter).
Zum Teil auch gerne einfach in einer StoredProc mit nem Cursor und Schleife in einzelne Transaktionen zerhackt. Dann müssen die anderen Transaktionen nicht unnötig warten.

Die Tabellen befinden sich in der selben DB, ich verschiebe sie nur zum verarbeiten in eine work-tabelle und danach in eine history, um den Datenbestand beim Verarbeiten so klein wie möglich zu halten da sich in der Work-Tabelle nur die Datensätze zum aktuellen Vorgang befinden.

In diesen Fällen bevorzuge ich Temporäre Tabellen oder - wenn es die performance zulässt - Tabellenvariablen. Das erspart die Aufräumarbeit und man kann das ganze später auch von unterschiedlichen Stellen (Threads) anwerfen, ohne dass die "Worktabelle" von allen belegt wird.

😃

Xynratron

18.04.2011 - 10:59 Uhr

huhu,

vielen dank für den Link, der ist sehr informativ. Allerdings auch schon etwas älter, hat sich da nichts getan?

Naja, Grundlegend muss doch alles beim alten bleiben, oder?

Von ODBC würde ich generell abraten: alt, langsam, existiert nur noch aus Kompatibilitätsgründen.

Dass die Zieldatenbank nicht bekannt ist, ist extrem ärgerlich, denn man muss trotz allem die eigentlichen DB-Statements (Insert, Update etc.) Datenbankspezifisch halten. Hier kommt man also nie um eine Anpassung auf eine bestimmte DB herum.

Dafür gibt es aber OR-Mapper:

Wenn Du Datenbank-unabhängig programmieren willst dann schau Dir die O/R-Mapper an, z.B. Entity Framework.

😃

Xynratron

28.03.2011 - 22:16 Uhr

huhu,

naja, die Libs sind erstmal nicht im CE-Framework vorhanden, also geht es erstmal nicht.

Ein Problem - warum es vermutlich nicht wirklich funktioniert - ist, dass alle diese "kleinen" Geräte Applikationen abschalten, welche "subjektiv" keine Rechenzeit brauchen. Demzufolge ergibt die Implementation eines Services, welcher immer mal wieder Rechenzeit braucht aber keine Foreground Anwendung ist, keinen Sinn. Auch wenn der Server (Service) eine Anfrage bekommt, hat er keine Rechenzeit, Interrupts etc. um darüber überhaut eine Information zu bekommen.

Vielleicht kannst du auf andere Libs ausweichen oder ein Polling des "Servers" einbauen.

😃

Xynratron

28.03.2011 - 21:52 Uhr

huhu,

per WMI kann man die Netzverkverbindungen auslesen, hier sollte auch ein Counter für die Netzwerkgüte dabei sein.

😃

Xynratron

28.03.2011 - 20:52 Uhr

huhu,

Soweit ich weiß, können doch Klassen in C++ ohne einen Namespace deklariert werden.

in c# geht das auch. Da ist es dann - wenn es wider erwarten nicht gefunden wird - "global::"

Aber in c# gibt es vermutlich auch dasselbe Problem, wenn eine Klasse und ein Namespace in dem Fall denselben Namen haben.

😃

Xynratron

28.03.2011 - 20:45 Uhr

huhu,

@Xynratron: Da wird ein Bier beim Oktoberfest fällig! 😉

Nur weil Du ein Oleobject per Access hineingeladen hast, ist dieses Problem entstanden.

Bild per Code ein- und wieder ausgelesen. Und so funktioniert es jetzt ohne Probleme und das Problem mit dem Offset fällt auch weg

Du zahlst 😃

28.03.2011 - 20:30 Uhr

huhu,

ein paar Sachen schliesst Du bereits aus: mangelnde Rechte lösen eine Exception aus, Windows Anmeldung bzw. SQL-Server geht auch. Fehlende Rechte bei SP lösen auch ne Exception aus.

Ich finde jetzt nur 4 Erklärungen:

a) Es gibt eine zweite Instanz von SQL-Server mit den DB's und eine hat die Datenstruktur aber keine Daten. (oder tatsächlich ein ganz anderer Rechner/Server?) Im SSMS verbindest und testest du auf die andere DB mit Daten.

b) Es gibt eine Daten-Einschränkung auf den Benutzer (ja, man kann unter SQl-Server angeben welcher Benutzer welche Daten selectieren darf) - wenn das aber nicht explizit eingestellt wird, kommt es nicht vor.

c) Abfrage über SP's mit expliziter Authetifizierung (selst gebaut) welche dann nichts oder "-1" zurückgibt.

d) der DB- oder BI-Layer hält die Daten zurück und/oder filtert die aus.

Lösung: mal SQL-Profiler anwerfen und gucken was da an Anfragen wirklich reinkommt. wenn nicht kommt, dann ist es der falsche Server, wenn der Server Daten rausgibt ist es das Programm.

😃

Xynratron

PS: wo wird denn "-1" zurückgegeben? kein SQl-Server macht das freiwillig.

08.03.2011 - 22:22 Uhr

huhu,

definitiv subjektiv 😃 Ja, die Contentfarmen sind weg. Aber jetzt gehts mir bei Google fast wie bei Bing - Verweise auf die MSDN rangieren weiter hinten. (hab ich bei Bing eh noch nie verstanden)

heute hatte ich mal nach - aufgrund einer Frage hier im Forum - mal nach "sqldatareader wrong special chars" gesucht (und alternativen). Naja, grad nochmal versucht, aktuell sind die Treffer deutlich besser. Heute Mittag gab es nur einen wirklich guten Treffer.

Mal gucken 😃

xynratron

08.03.2011 - 22:07 Uhr

huhu,"

Hab in einem Forum gelesen dass man erst ab 78 auslesen muss. Alles davor sei nur header.

ok, denjenigen fordere ich gerne auf dem Oktoberfest heraus. Vielleicht wirds mir dann klar. Aktuell behaute ich aber: absoluter Blödsinn. Keine DB "verschwendet" mal kurz XX Bytes.

Wenn Deine Datenbank dir Daten liefert, dann lies bitte immer alles. Wenn es Probleme gibt, dann kann mann immer noch den Stream analysieren.

😃

Xynratron

08.03.2011 - 22:02 Uhr

huhu,

als erste mal - hier gibts c# und sql tags - dann kann man das ganze besser lesen.

Aber zu deinem Problem. Was bedeutet ineffizient? 6 Queries stören eine DB im allgemeinen nicht wirklich. Du kannst mal den Profiler laufen lassen, um die ineffiziez zu überprüfen (alles gen > 200ms von der DB ist definitv ineffizient).

Ok, wen du das getestet hast, dann bemüh mal die Stopwatch (sieht bei Dir nach Winforms aus) um nen Zeitfresser zu finden - alternativ nen Profiler dazwischenschalten.

Deinn Code an sich sieht nicht übel aus. Ich bin mir jetzt abe nicht sichre ob das ganze nicht in nem Dataset am Client passiert.

Linq und Konsorten sind nur eine Möglichkeit "eleganter" zu programmieren, in der Laufzeit hilft es nur, wenn man extrem grobe Schnitzer macht. Ansonsten sind diese Bibliotheken im allgemeinen etwas langsamer als selbst programmiert. Allerdings so wenig, dass sich es definitiv lohnt, diese zu verwenden (aufgrund der persöhnlich gesparten Arbeit).

😃

Xynratron

08.03.2011 - 21:32 Uhr

huhu,

klar geht es auch ohne "IIOP" (ich kenns nicht mal) - oder sonstige Bibliotheken. Die Kapseln auch nur "Dein" Problem.

Prinzipiell würde ich mir aber definitiv mal WCF angucken. Das kapselt auch remoting (zusätzlich zu anderen sachen) und kann alles was du brauchst. Ausserdem guckt es erstmal komplex aus, ist aber eigentlich ganz einfach.

😃

Xynratron

08.03.2011 - 21:17 Uhr

huhu,

ja, der Stream für Image ist "ungültig".

für Version 1: ExecutScalar liefert nur Feld 1 aus Datenzeile 1 zurück - ich bezwefle, dass hier das Image als Bytes komplett zurück kommt.

zu 2. Warum wird erst ab Byte 78 gelesen?

schau Dir mal http://msdn.microsoft.com/de-de/library/87z0hy49.aspx an, da gehts um genau dieses Thema.

😃

Xynratron

08.03.2011 - 20:50 Uhr

hi Mike,

naja, wenigstens reagierst du Fix auf Fragen und Antworten. Andere schaffen nichtmal das. Aber leider bist Du wiedermal ein etwas schlechtes Beispiel. Ich persönlich schimpfe meine (IT-)Lehrlinge immer kräftig, wenn sie mit einer Frage/Problem kommen, ohne beschreiben zu können, was sie eigentlich dazu bewegt hat, zu mir zu kommen.

Für die Zukunft, guck Dir bitte immer genau an, in welcher Umgebung "Der Fehler" auftritt. Dann findet man deutlich schneller Hilfe - sei es nun im Forum oder nur "per Google" - immer Hilfe. Und, je besser ein eigenes Wissen um die Materie ist, desto besser findest du auch die Ansatzpunkte.

HappyCoding

Xynratron

PS: und benutze doch Doppelpunkte statt Ausrufezeichen.

08.03.2011 - 08:19 Uhr

huhu,

Wie bekomme ich denn raus wo die Zeichen, die ja noch richtig in der DBZelle stehen verädert werden?

Die Daten in der "DBZelle" werden nur im Managementstudio richtig angezeigt. Geändert werden sie nirgends, nur die Anzeige ist falsch.

Überprüf bitte, ob die Daten vom Webservice richtig kommen (z.B. per Fiddler) und der Client das ruiniert oder ob am Webservice eine Änderung vorgenommen werden muss.

😃

Xynratron

07.03.2011 - 22:27 Uhr

huhu,

willst du nicht jede Funktion/Command anpassen? Also etwas "Allgemeines" haben, was unabhängig die Zeit misst?

😃

xynratron

07.03.2011 - 22:10 Uhr

huhu Timo,

naja, deine Fragen sind ihmo nicht so abwegig wie es gerade erscheint. Genau das passiert ja in jedem P2P Program: Daten werden verteilt und jeder vertraut darauf, dass der (später) resultierende Hash die Originaldaten wiederspiegelt. Das Funktioniert bekanntermaßen auch sehr gut und verlässlich.

Was nicht funktioniert, sind Daten, welche (potentiell) nur einem Benutzer zugute komme sollen. Denn diese daten muss man übertragen - womit die Idee der Netzwerklast schon wegfällt - und das immer nur zu "dem einen Client".

Ein Hash ist immer nur bedingt gut. Wenn die Datenmenge sehr klein wird, dann reduziert sich die Menge der möglichen Hashes auf das maximum dieser Datenmenge. Also z.B. Daten sind nur ein Buchstabe ("A-Z") - dann gibts auch nur 26 mögliche Hashes. Bei sehr grossen Datenmengen reduziert sich wiederum die Nachprüfbarkeit. Hash-Algorithmen sind nur möglichst gut mathematisch analysiert - aber es garantiert niemand, dass sie nicht "versehentlich" bei großen Datenmengen eine kollision produzieren. (kleine Mengen lassen sich berechnen, große nicht mehr) Aber: ja, es funktioniert auch bei großen Datenmengen (aktuell)^^

Crythographie ist übrigens bei deinen Überlegungen nochmal ein anderer Punkt. Verschlüsselung kostet immer Serverkapazität (CPU, RAM, Nertzwerklast) - womit ja deine anderen Punkte angesprochen sind. Ok, hier gibt es sehr gute Lösungen dafür (eine extra Crytobox für SSL vor den eigentlichen Servern) aber es ist imho nicht das was du meintest.

Wenn Du dich für das Thema interessierts, kann ich leider kein Buch empfehlen, nur Richtung. schau Dir an, wie https (ssl) funktioniert, Unterschiede zwischen synchroner und asynchroner Verschlüsselung, Unterschiede zwischen (crypto)Hashes; da reicht ja auch schon mal Codierungen auf Netzwerkkabeln als Grundlage anzugucken. Man muss ja immer davon ausgehen, das viel clevere Leute sich da schonwas dabei gedacht haben.

😃

Xynratron

07.03.2011 - 21:25 Uhr

huhu,

hab durch Zufall mitbekommen (heise) dass Google seinen Suchindex "verbessert" hat.

Naja, ich hab schon von Tagen festgestellt, dass meine Suchergebnisse schlechter geworden sind. Ich such auch fast auschschliesslich nach Programierer-Problemen - da helfen Seiten, welche nur andere Seiten wiedergeben und deswegen von google entfernt wurden - aber meine Suche ist subjektiv gute 100% langsamer geworden.

Wie gehts euch?

😃

xynratron

07.03.2011 - 21:20 Uhr

huhu,

Hab vor längerer Zeit mal ein System so implemetiert (Addin wird anhand von Job in Db geladen) und habe - in derselben AppDomain - recht gute Erfahrungen bzgl. Geschwindigkeit. Das hat aber auch seine Grenzen, ca. 1000 Transaktionen/Sekunde macht das Ding, allerdings sind die DB-Aufgaben auch nicht ganz trivial.

Damals hatte ich einen Artikel von den Machern des AddIn-System gefunden, der die Unterschiede bei der Geschwindigkeit angibt. Imho war damals der Übergang von unterschiedliche AppDomains bei ca. 3000 / Sekunde.

Den Artikel (Blog Eintrag) müsste man mal wieder suchen / finden.

😃

Xynratron

07.03.2011 - 21:12 Uhr

huhu,

Wenn ich getdate() als ComputedColumnSpecification eintrage dann schreibt er mir für jede neue Zeile das Datum an die entsprechende Stelle.

Die Annahme ist falsch. Du wirst bei jedem Select den aktuellen Wert von getdate() zurückbekommen (also jetzt den 07.03.2011, morgenden 08.03.2011). Computed Columns werden nur (maximal) solange gespeichert, wie sich ihr Wert nicht ändert. getdate() ändert sich dauernd.

Das Beispiel von FZelle zeigt das korrekte Verwenden von ComputedColumns.

Bitte einfach ausprobieren^^

😃

Xynratron

07.03.2011 - 21:02 Uhr

huhu,

Müsste es vielleicht nvarchar sein?

muss nicht, kann aber. In der Tat ist nvarchar unicode und varchar abhängig von der Einstellung in Server, Datenbank, Tabelle, Feld. Lässt sich bei allem per Collate einstellen.

Überprüf bitte, ob die Daten vom Webservice richtig kommen (z.B. per Fiddler) und der Client das ruiniert oder ob am Webservice eine Änderung vorgenommen werden muss.

Prinzipiell sollte man die "String-Spalten" am DB-Server auf Unicode umstellen, sonst wirds auch nix mit griechisch, türkisch oder gar chinesisch.

😃

Xynratron

07.03.2011 - 20:41 Uhr

huhu,

Das "Gruppiert" bei den Indizes ist ein "Clustered Index" - nur zur Erklärung.

Wie ist die Maschine ausgestattet und kannst du das mal auf eine aktuelle Workstation portieren? (SQL-Server installieren, Backup einspielen, Abfrage 5 mal ausführen)

FieldAttributes ist ja "nur" ein Int. Kannst du mal eine "Select top 10" gegen einen select top "1000" testen - und lass mal den Profiler nebenbei laufen; zusätzlich im Query Analyser die Kosten und Dauer mitloggen lassen. (Profiler gabs auch schon bei 2000; vielleicht gabs hier auch schon die Duration, ansonsten Start und End protokollieren und den Unterschied nehmen)

🙂

xynratron

07.03.2011 - 14:38 Uhr

2-5% CPU Auslastung zeigt der Taskmanager während der Ausführung der Query an.

Der Einwand von MrSparkle ist berechtigt

Wenn du nen Index auf der varchar-Spalte hast, dann macht das keinen Unterschied. Da du nur sehr wenig CPU-Last hast, bedeutet das, dass wenig zu rechnen ist (=keine Stringvergleiche) denn ohne Index würde hier deine CPU-Last schnell auf 100% steigen.

Ich tippe jetzt wirklich drauf, dass dein Flaschenhals der Datendurchsatz zur Festplatte ist. Vermutlich hat der Server deutlich zu wenig Ram, und muss sich den Index und dann die Daten immer häppchenweise von der Platte laden.

Im günstigsten Fall ist der Durchsatz von/zur Festplatte sehr gering und die DB (oder wenigstens die Indizes) liegt praktisch vollständig im Arbeitsspeicher. Dann merkt man auch, dass die CPU-Last hochgeht und der SQL-Server das arbeiten anfängt.

Nachdem es im SQL Query Analyzer genauso langsam ist, liegt es auch definitiv nicht an deiner App.

Zum Clustered Index: Man kann (und sollte unbedingt) einen Index pro Tablle als Clustered definieren. Im Normalfall ist das dann automatisch der Primary Key. Der Clustered Index spiegelt die physikalische sortierung der Tabelle wieder. Manchmal kann es hier sinnvoll sein, das zu ändern, aber meistens nicht.

😃

xynratron

07.03.2011 - 13:39 Uhr

huhu,

Im Prinzip könntest du die Projektbeschreibung aber auch in eine andere Tabelle auslagern, dann hast du in der großen Tabelle nur einen Fremdschlüssel auf das jeweilige Projekt. Damit ersparst du dir den Stringvergleich bei jedem Datensatz, und stattdessen wird nur ein Integer verglichen. Das sollte schon eine Menge Performance mit sich bringen.

Das wäre die richtige Richtung zur Normalisierung, aber bei der Performace dürfte sich hier nicht viel tun. Ein string als Index wir nicht als Liste von Strings abgelegt, sondern als Baum.

😃

Xynratron

07.03.2011 - 13:35 Uhr

huhu,

jetzt war ich zu spät^^

Ein count(*) ist immer schneller, weil er keine Daten "lesen" muss. wobei hier 5-10 sek. schon langsam sind.

die Daten im Management-Studio werden auch einfach mit einem DataReader geholt, hier interessiert eigentlich die Zeit, wenn alle Daten gelesen wurden, also die Query als "Fertiggestellt" gilt. (unten rechts in der Statusleiste). Eventuell auch mal einfach den SQLProfiler mitlaufen lassen und gucken was der sagt.

Der DataReader kann ja schon gelesen werden, bevor alle Daten da sind. Du bekommst einfach, sobald die Query die ersten Treffer hat, auch schon die ersten Daten zurück. Deswegen hängt dein Programm auch nicht bei "ExecuteReader()" sondern erst in der Read()-Schleife. Das bedeutet, dass die Daten sehr langsam in dein Programm fliessen.

😃

Xynratron

07.03.2011 - 13:29 Uhr

huhu,

hast du nen Clustered Index drauf?
Was sagt der Server, wenn du die Abfrage ausführst? (hoher Datendurchsatz auf der Platte, Server sowieso schon immer mit 130% Last etc.)

😃

xynratron

07.03.2011 - 11:35 Uhr

huhu,

ja, dann versuch doch einfach mal vom (laufenden) Dienst aus, die user.config zu speichern. Wenn das geht, dann kannst du mit den Konfigurations-Programm dem Dienst einfach imemr seine config unterschieben. Da sie unter einem bestimmten Benutzerkonto (und sei es System oder Networkservice) laufen sollte das möglich sein.

Alternativ speichern Dienste Ihr Konfig in der Registry unter: HKLM\System\CurrentControlSet\services\MyService\Parameters

Dienste sind ja eigentlich nichts für eine "Benutzerkonfiguration" - deswegen würde ich abwägen wieviele Konfigurationsparameter notwendig sind:

sinds wenige, dann in die Registry
sinds viele, dann per app.config im Installationsverzeichnis des Dienstes.

Da "Administratoren" die Konfig ändern können sollen, ist beides von den Rechjten her kein Problem.

😃

Xynratron

02.03.2011 - 22:25 Uhr

huhu

es gab unter win32 imho mal ein "Share Deny None" - hab dazu aber grad keine Entsprechung im .net gesehen noch kann ich ne Garantie abgeben.

Dein "ReadWrite" sollte es eigentlich bringen.

😃

Xynratron

02.03.2011 - 22:00 Uhr

huhu,

prinzipiell ist mir dein Code gerade zu schlecht zu durchschauen^^.

Natürlich können 2 verschiedenen Datentypen (aus Linq und ähnlichem) dasselbe Interface implementieren. Allerdings wissen die Insert-Methoden der ORMapper dann natürlich nicht, welches konkrete Objekt gemeint war, bzw. können die Ziel-Tabelle nicht finden, wenn nur noch das Interface übergeben wird.

😃

Xynratron

02.03.2011 - 21:42 Uhr

huhu,

hab oben (gleich) noch nen Edit.

naja, wenn Du einen Vorteil nachweisen willst, dann sollte man das erstmal ohne linq machen. Aber, ok, linq2sql ist ja auch nur ein OR-Mapper in dem Sinne, und ob dieser sqlFileStream direkt unterstützt ist mir nicht bekannt.

Aber, man sollte sich immer mal mit den Grundlagen (darunter, also unter Linq2Sql) bescheid wissen, dann kann man auch die höheren Probleme leichter identifizieren.

Leider fehlt mir persönlich die Zeit, dieses Problem mal auszuprogrammieren.

😃

Xynratron

02.03.2011 - 21:27 Uhr

huhu,

naja, ich meinte, du sollst die datei nicht selbst in den Arbeitsspeicher lesen und dann verarbeiten.

Streams sind ja dazu da, dass man sie - ohne die Daten selbst lesen zu müssen - verwenden kann. Für Dein unterfangen gibt es a) SqlBytes (Varbinary) und B) SqlFileStream (FileStream)

Bei ersterem kannst du deinen Filestrem direkt im Constructor übergeben und bei zweiteren "reinschreiben". Da zweiterer auch von Stream erbt, müsste

myFileStrem.CopyTo(mySQLFileStream)

funktionieren.

probiers mal aus. Tatsächlich sind hierzu die Tutorials im Internet recht dünn. Vielleicht kannst du ja eine kleine Anleitung dazu machen? Also endlich mal eine, die nicht nur liest und updated, sondern auch nen anständigen Insert macht.

Edit: Da ist was: http://www.codeproject.com/KB/database/SqlFileStream.aspx
Edit2: im Beispiel wird auch ReadAllBytes verwendet. Das sollte man entsprechend ersetzen.

😃

Xynratron

02.03.2011 - 20:56 Uhr

huhu,

"Outlook" benachrichtigt mich gerade mal Minutengenau - auch sind Sekunden-Timer etwas überdimensioniert.

Ich würde eine Mischung machen: Erst die "die Events während des Tages abrufen" - das sind diejenigen, für welche informiert werden muss.

Zusätzlich gibt es aber jene, welche Tagsüber von anderen in die DB eingefügt werden. Klar kann man diese per polling "jede Sekunde" aus der DB abholen, aber naja, polling ist immer schlecht.

Dafür gibt es in diesem Fall SqlDependency. Schick eine Abfrage an den SQL-Server und du bekommst Antwort wenn sich das ursprüngliche Ergebnis ändert (also ein Datensatz dazu kommt oder sich der Zeitpunkt ändert).

😃

Xynratron

02.03.2011 - 20:37 Uhr

huhu,

RichTextBox? die kann RTF.

😃

Xynratron

02.03.2011 - 20:34 Uhr

ok, jetzt hab ich mir den Code doch noch angesehen. Die Daten vorher in den Arbeitsspeicher zu lesen, das kann nicht die richtige Lösung sein. Ich Tippe darauf, dass man dem Command (zum Insert) nur einen Stream-Parameter mitgeben muss, und der Rest vom Framework erledigt wird. Vielleicht muss man auch selbst lesen, aber dann gilt das was immer gilt: nur weil man es kann muss man nicht 4 GB in den Arbeitsspeicher einlesen.

😃

Xynratron

02.03.2011 - 20:22 Uhr

huhu,

ich hab jetzt nicht deinen Code angeschaut, aber deine Frage (was schneller ist) lässt sich leicht in zusammenfassen:

Für SQL-Server wurde der Filestream Datentyp entworfen, um die Geschwindigkeit beim Zugriff auf Dateien im NTFS-Dateisystem mit der Geschwindigkeit im selektieren von Daten im SQL-Server zu verbinden. Das bedeutet:

SQLServer wird beim lesen von BLOB immer langsamer sein, denn hierzu müsssen die Daten von der Festplatte durch den SQL-Server zum Client geschickt werden. Der Zugriff bei FileStream lässt den SQL-Server aus. Damit fehlt eine Schicht und der Vorgang ist schneller.

Da der Umgang mit Filestream einen erhöhten Overhead an die Umgebung (Windowsauthentifizierung und Freigabe am Server) erfordert, hätten die Jungs und Mädels - welche sich das ausgedacht aben und garantiert einen Level über unseren Programmierkünsten schweben - das nicht gemacht, wenn es langsamer wäre.

😃

Xynratron

PS: auch wenn man nicht immer alles glauben sollte, hier maße ich mir nicht mal an, auch nur nen aussagekrätigen Performace-Test zu schreiben.

Edit: hier gibt es auch Tags für Code

02.03.2011 - 20:00 Uhr

huhu,

Das habe ich auch mal gelernt, aber so lange nicht mehr gebraucht

imho kommt das jetzt darauf an wie lange das her ist^^ Denn "damals" war das üblich und wir versuchen alles, damit sich die Programmierer auch wieder an "die richtige Art und Weise" (von damals) erinnern.

😃

xynratron

28.02.2011 - 20:31 Uhr

huhu,

wieso nimmst du nicht einen DateTime? Der würde dann auch nicht sortiert wie es der String "Jan. 05" wird.

😃

Xynratron

27.02.2011 - 22:33 Uhr

Dem kan ich mich nur anschließen.

Denn genau das ist der Grund, warum man - von der anderen Seite - versucht, Elemente eines Webservers auf mehrere Server zu verteilen. Z.B. bauen die aktuellen Webbrowser nur 2 Verbindungen zu einem Server auf. Deswegen versucht man im leichtesten Fall, statische Elemente auf ein Content-Network auszulagern. Damit hat der Browser 2 Server und macht 4 verbindungen auf. Naja, übertreiben darf man es nicht, sonst macht man die Leitung zum Client dicht.

😃

Xynratron

27.02.2011 - 16:51 Uhr

huhu,

ja, wäre doch einfach möglich, indem du für die Thread.Id guckst, ob er gerade gestartet wurde, und wenn ja, dann einen Sleep einbaust.

Aber, ich kann beim besten Willen nicht erkennen, warum es sinnvoll sein sollte, einen Thread schlafenuzlegen, wenn man ja mehrere Threads benutzt, um schneller zu werden?

😃

Xynratron

27.02.2011 - 16:43 Uhr

huhu,

erstmal Vorweg: Bilder sind Bilder und liegen in einem bestimmten Format (png, jp, bmp, gif, tga usw.) vor. Ein System.Windows.Cntrols.Image ist ein Steuerelement und zeigt nur ein Bild an. Das Bild, welches angezeigt werden soll, wird dann z.B. über die Source-Eigenschaft festgelegt.

Zu deinem Fehler: welchen Fehler bekommst du genau?

siehe [Hinweis] Wie poste ich richtig? Punkt 5 und [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)

😃

xynratron

27.02.2011 - 16:30 Uhr

huhu,

welchen Fehler genau bekommst du?

😃

xynratron

21.02.2011 - 11:36 Uhr

huhu,

Du machst leider einen Denk-Fehler:

Aber die Applikation selber ist ja trotzdem gestartet und läuft. Im Quartz.net-Framework kann ich ja Klassen hinterlegen, die aufgerufen werden, wenn ein Job ansteht. Diese Klassen sind ja solange für das Framework greifbar, wie die Web-Anwendung aktiv ist.

Und genau das eignet sich nicht für die Jobverarbeitung. Denn die Webanwendung ist zwar aktiv, aber nur solange sie benutzt wird. Der IIS schaltet den Workerprocess (Apppool) aus, wenn 20 Minuten* lang von außen keine Anforderung kam. Hierbei werden auch deine internen Threads abgeschossen. Und genau das willst du ja nicht, dass plötzlich Nachts alle Bauschleifen nicht mehr abgearbeitet werden und dann deine Datenbank/Applikation einen für den Benutzer nicht nachvollziehbaren Zustand hat. ("Da habt ihr euch aber um 2 Bau-Ticks verrechnet!!11einElf!)

Das ganze ist also nur zu lösen, indem man das unabhängig von äußeren Einflüssen (IIS) hält. Ein Windows-Service wäre Ideal, für den Anfang reicht aber wohl ein kleines (Konsolen)Programm, dass im Hintergrund läuft oder so. Die Intelligenz des Programms kann man dann in einen Service übertragen. Debuggen lässt sich aber das Programm leichter.

😃

Xynratron

*): die 20 Minuten sind default und lassen sich konfigurieren. Aber der Workerthread wird auch "recycled" - sprich abgeschossen und ein neuer gestartet.

16.02.2011 - 22:03 Uhr

huhu,

Volltextsuche vs. Like - da hatten wir mal eine lange Diskussion. Das ist (auch lt. Microsoft) nicht performanter. Denn das lässt sich nciht per se sagen. Wenn Du eine Spalte mit großen Texten hast (z.b. die 100.000 Worddokumente der Firma), dann kann es performanter sein - muss aber nicht. Für ein Suchsetting ala "in welcher Spalte steht das" trifft es wohl am wenigsten. Volltextsuche wird dann performant, wenn die zu durchsuchenden Daten gross sind (nicht in Anzahl von Zeilen, sondern in Menge pro Zelle)

Desweiteren hat die Volltextsuche ein paar Mankos bezüglich der Syntax - mangels Erfahrung weis ich die nicht mehr - aber LIKE hat sich als im allgemeinen besser herausgestellt.

😃

Xynratron

16.02.2011 - 21:49 Uhr

huhu,

oder anders: Linq ist nur eine Hilfestellung. Man kann alles was Linq macht auch "per Hand". Also sieh Dir mal an, was FZelle gesagt hat, überlegt wie man das machen kann; und dann kann man auch mit Linq eine "Abkürung" für den Code suchen/finden.

😃

Xynratron

16.02.2011 - 12:48 Uhr

huhu,

, testweise ein ADO.NET Entity Data Model zu erstellen und dann in der app.config den ConnectionString herauszukopieren.

ich halte Projektsettings-> Neue "Verbindungszeichenfolge" für noch einfacher 😃