2010-12-29 3 views
0

zuerst - ich möchte mich für mein abgeschlagenes Englisch entschuldigen.Wie kann ich mein Programm reaktionsfähiger machen? (Programm, das mindestens 200 Dateien lädt) - ich könnte 1 Idee haben

Ich baue ein Programm, das eine Menge Dateien verwendet. Ich habe viele foreach-Schleifen, die durch die Festplatte und diese Dateien (mindestens 200 Dateien - 600 Bytes pro Datei im Durchschnitt) schleifen, die Schleife verwendet XPath, um nach Werten in der Datei zu suchen (die Dateien sind natürlich XML-Dateien)

Ich muss einen Weg finden, mein Programm reaktionsfähiger zu machen - ich dachte an eines, das folgendes ist: Computerspeicher hat eine höhere Ladegeschwindigkeit als Computerhardware - und ich dachte - vielleicht sollte ich diese Dateien in die Speicher und als Schleife der Speicher statt die Festplatte von looping .., nebenbei bemerkt, wenn jemand kann mir sagen, wie viel schneller Computer-Speicher (von harddisks) ist als dank

Vielen dank im fortgeschrittenen .. Din

wenn jemand nicht mein Englisch verstehen Ich werde versuchen, wieder zu erklären

+0

Meinst du "responsive" oder "schneller"? –

+0

@Marcel Meine Vermutung ist, dass das OP sie aufgrund von Sprachbarrieren gleich ansieht ... obwohl ich weiß, dass reaktionsfähig sein kann, dass Arbeit auf dem UI-Thread ausgeführt wird ... und schneller ist die Rate bei der Analyse der Daten .. .fair question ... –

Antwort

2

Der beste Ansatz, den ich denke, ist PLINQ in C#4.0. Gruppieren Sie diese XML-Dateien und fragen Sie sie parallel mit LINQ-to-XML ab. Das folgende ist ein einfaches Beispiel, das alle XML-Dateien in C: \ xmlFolder lädt und die Dokumente auswählt, die ein Element enthalten, dessen Name "Schlüssel" ist.

List<XDocument> xmls = Directory.EnumerateFiles(@"C:\XmlFolder").AsParallel() 
          .Select(path => XDocument.Load(path)) 
          .Where(doc => doc.Descendants() 
              .Any(ele => ele.Name.Equals("key"))) 
          .ToList(); 
0

Sie sollten die XML-Dateien in einem anderen Thread analysieren und Objekte mit den erforderlichen Informationen zu erstellen, auf diese Weise Sie sofortigen Zugriff auf die Informationen haben.

+1

Wenn Sie diese Route gehen, stellen Sie sicher, was Sie nicht mehr benötigen, da das Halten aller Daten im Speicher nicht benötigt wird und Probleme verursachen, wenn Ihre Dateigröße zunimmt ... –

+0

600 Dateien * 1Kbyte = 600Kbytes also momentan und auf mittlere Sicht keine Notwendigkeit, das zu tun (IMHO). –

+1

Es ist das beste Verfahren ... Festhalten an etwas, das Sie nicht brauchen, hat keinen Wert und lässt nichts zu skalieren ... –

0

Definieren Sie "reagierend". Meinst du, dass du möchtest, dass UI-Cues weiterhin passieren oder dass du während der Verarbeitung der Dateien weiterhin in der Lage bist, andere Dinge zu tun?

Der ehemalige ist einfach, Sie können einfach in den gelegentlichen Application.DoEvents() in Ihren Schleifen werfen. Dadurch wird die Benutzeroberfläche aufgefordert, alle wartenden Hinweise auszuführen (z. B. das Fenster zeichnen usw.).

Letzteres wird Multi-Threading beinhalten. Eintauchen in das ist ein bisschen komplexer, als in einem Absatz oder zwei gelehrt werden kann, aber einige Google-Suchen nach "C# .net Multithreading-Tutorial" sollte eine Tonne Ergebnisse ergeben. Wenn Sie mit dem grundlegenden Konzept dessen, was Multithreading bietet, nicht vertraut sind, kann ich es weiter erklären.

+1

Application.DoEvents() existiert nicht in WPF, nicht sicher, was die App des OP ist ... –

+0

@Aaron: Guter Punkt. Ich nehme an, dass ich WinForms angenommen habe, ohne es so oder so zu sagen. – David

+0

Wenn ich "reaktionsschnell" meine, habe ich einen Texteditor in meinem Programm und wenn der Benutzer etwas eingibt, durchläuft das Programm die Dateien, indem er diese Dateien durchläuft, den Cursor für eine Sekunde "anspricht" und dann wieder auftaucht ist, weil das Programm durch Dateien läuft, die den Computer für eine Sekunde stecken lassen - meine CPU-Auslastung steigt in 20% für eine Sekunde) – dinbrca

-5

Sie können die Datenbank zum Speichern von XML-Dateien verwenden, sie wird schneller, sicherer und zuverlässiger als Ihr aktuelles Schema sein. Sie können Indizes erstellen, der gleichzeitige Zugriff ist aktiviert, XQuery/Xpath wird unterstützt und viel mehr "Pluspunkte".

Wenn Sie nur XML-Dateien haben, können Sie Native XML-Datenbanken berücksichtigen. Wenn Sie auch andere Datentypen haben, können Sie XML-fähige DBMLS (wie Oracle oder DB2) in Betracht ziehen.

+2

-1 für die Verwendung von DB vorschlagen, ohne eine Ahnung zu haben, was das Programm macht, warum usw., aber wissen, dass es 120K Daten gibt. –

+0

Er redet über 200-600 Dateien und fragt alle ab. Nachdem die Datenbank richtig eingestellt wurde, sind alle Abfragen viel schneller als alle anderen "brillanten" Nicht-DB-Ideen. Warte auf dich bessere und schnellere Idee, wenn du es getan hast. – oop123123

+0

Er hat keine 200-600 Dateien - bitte lesen Sie die Frage noch einmal. Ich werde nichts optimieren, was ich nicht verstehe. DB für alles zu verwenden ist eine wirklich schlechte Idee. –

0

Verwenden Sie einen BackgroundWorker oder einen ThreadPool, um mehrere Threads für die E/A zu erzeugen, und lesen Sie die Daten dann in eine Warteschlange (vorausgesetzt, die Gesamtgröße Ihrer Daten ist nicht zu groß). Lassen Sie einen anderen Thread von dieser Queue ablesen und führen Sie Ihre interne xPath-Logik aus, um aus diesen Dateien alles herauszuholen, was Sie benötigen.

Im Wesentlichen, denken Sie an es als eine Instanz der Producer/Consumer design pattern, wobei Ihre I/O-Leser Threads Produzenten sind, und Ihre XPath-Logik Threads sind Verbraucher.

Der Typ des Objekts in der Warteschlange könnte nur ein Byte-Array sein, aber ich würde vorschlagen, eine benutzerdefinierte C# -Klasse, die das Byte-Array enthält, sowie einige der Metadaten der Datei für den Fall, dass Sie es für was auch immer benötigen Grund.

Verwandte Themen