Laden...

Forenbeiträge von Hans18 Ingesamt 13 Beiträge

20.03.2013 - 08:58 Uhr

Guten Morgen,

ich muss einen Regex-String aus mehren Literalen zusammenfügen. Ich habe aber nun das Problem, dass Escape-Zeichen dupliziert sind. Beispiel:

public const string P1 = @"\\SAP[0-9]"
public const string CDS = @"\\CPRD[0-9]"
		
public static string PatternTest = P1 + CDS;

Ergibt laut Console.Writeline

\\\\SAP[0-9]\\\\CPRD[0-9]""

Wenn ich den Pattern in Expresso verwende geht es. Aber in C# wegen diesem Fehler nicht.
Wo ist mein Denkfehler????

05.03.2013 - 10:27 Uhr

Es ist eben ähnlich einem Dateisystem, und daher funktioniert Dein Vorschlag so nicht:
Ich habe einen Ordner, und will den kompletten Inhalt wissen, wobei ich diesen bei Beginn eben nicht kenne: Order durchsuche ich weiter, Dateien füge ich einer Liste hinzu.
Da dies parallel einfach schneller geht, da über Netzwerk, eröffne ich für jeden Ordner einen Task.

Ich kenne weder die Anzahl der Treffer, noch die Anzahl der Knoten bei Beginn.
Es ist nicht klar, wie ich die Menge der Tasks ermittle, oder bei einer BlockingCollection zum korrekten Zeitpunkt CompleteAdding ausführen kann, da ich nicht weiß, wo das Ende ist.

Ich habe also:

  • am Anfang einen suchenenden Task, für jeden Treffer neue suchende Tasks, da dies einfach schneller ist (Producer)
  • mehrere Consumer brauche ich eigentlich nicht, da das Consumieren der gefundenen Informationen (in diesem Beispiel die Dateien) an einer anderen Stelle ist.

Die Frage ist also:

  • wie kann ich bei mehreren suchenden Tasks feststellen, wann das Ende erreicht wurde und auf Task.Waitall() verzichten?

Ich habe noch eine Möglichkeit gefunden, indem ich einen ChildThread an das Parent "attache" damit spar ich das Wait.
Wirklich schön ist das aber auch nicht.

05.03.2013 - 09:20 Uhr

bei meinem Vorschlag werden alle Tasks einmal zu Anfang gestartet. Daher sind alle bekannt und das Warten auf sie ist kein Problem.

Damit kann ich mich irgendwie nicht zufrieden geben, da ich glaube, dass Du nicht zuende denkst.
Wenn ich nur 4 Unterknoten habe, dann macht es keinen Sinn am Anfang 500 Tasks zu schedulen. Wenn ich 5000 Unterknoten habe, macht es eventuell mehr Sinn statt nur 4 Tasks eben übertriebene 300 zu starten - eben wegen dem IO-Verhalten.

Du sprichst zwar von mehr Tasks als Cores, aber nicht wie Du die Anzahl ermittelst geschweige denn deren Antwort mit einer Nachricht bestätigst.

Es ist toll, dass Du mir hilfst, danke auch.
Aber die paar Brotstücke, die Du mir gibst, helfen auch nur bedingt. Es wäre also sehr nett, wenn Du mir vollständig erklärst, was Du überhaupt meinst.

Das ist eben nicht ganz trivial und da hilft mir auch der SyncQueue-Thread nicht. Da schreibst Du auch nur, dass eine Quit-Nachricht null sein kann oder nicht und man dieses eben definieren muss; aber im Sinne eines Pattern wird dort nichts erklärt.

05.03.2013 - 09:04 Uhr

Offensichtlich tut Task.WaitAll genau, was du willst. Wie ich schon sagte, ein einmaliges WaitAll am Ende ist sicher nicht das Problem.

Nein, und doch.
Sobald Task.WaitAll(taskList.toArray()) erreicht wird werden auf neue Tasks in "taskList" nicht gewartet!

In die Queue müsstest du natürlich für jede Task eine Ende-Nachricht stellen, damit sie weiß, dass keine Aufträge mehr folgen und sie sich selbst beenden kann.

Das sieht wie aus? Ich weiß eventuell nicht, was Du meinst.
Aus einer BlockingCollection wird das Element direkt genommen, sodass es dieses nicht mehr kenn.
Auf IsEmpty kann ich also nicht warten, weil der Task noch laufen und neue Elemente gefunden werden könnten.
Müsste also zwei Listen pflegen: anstehende und laufende Tasks..?

05.03.2013 - 08:49 Uhr

Hallo herbivore, danke.

Es werden innerhalb eines Knoten mehrere Abfragen, die über das Netzwerk gehen, durchgeführt. Ich kann nun alle erst mal sammeln und dann erneut eine Schleife durchlaufen, was ich als schlechter finde oder direkt bei einem Treffer die nötigen Informationen holen wie hier. Wenn ich den Betriebssystem-Scheduler richtig verstehe, dann sind mehr Tasks als Kerne durchaus schneller, da neue Tasks erstellt werden, während andere Tasks noch auf die Netzwerk-Antwort warten.
Wenn ich mit nur 16 Tasks (2x 8 Cores) ist es auch messbar langsamer.

Die SyncQueue ist ja nichts anderes als eine BlockingCollection.
Da bleibt immer noch ein Problem: woher, weiß ich, wann das letzte Element gefunden und bearbeitet wurde? Es gibt ein Ende, das erreicht wird, aber ich weiß nicht wann.
Es kann ja eine Action aktiv sein, während aber die Queue schon leer ist.

05.03.2013 - 08:14 Uhr

Das ist Absicht in diesem Fall. Es muss nach außen hin sequentiell sein, der Inhalt soll aber rekursiv und möglichst schnell bearbeitet werden.

Die Variante erspart mir 70% der Zeit, aber ich finde das mit Task.WaitAll() nicht gut.
Es ist ja nicht nur ein Task, sondern es wird für jeden Subordner ein weiterer Task erstellt. Je nach Struktur sind das also sehr viele Tasks, die auch das gewünsche, sehr schnelle Arbeiten umsetzen.

Events gehen nicht, da ich nach außen nicht asynchron arbeiten darf.

05.03.2013 - 08:03 Uhr

Guten Morgen,

ich habe eine Methode, die rekursiv arbeitet.
Als Vergleich nehmen wir einen Ordner, der Subordner hat. Ein Baum.


        public void RecFolder( DirectoryInfo dirInfo )
        {
            foreach ( var dir in dirInfo.EnumerateDirectories( ) )
            {
                RecFolder( dir );
            }
        }

Damit das ganze schneller läuft möchte ich das Parallel umsetzen..
Mir ist klar, dass das mit den Ordnern so keinen Sinn macht, aber ich will damit ja keine Ordner durchsuchen. Es ist nur ein Beispiel.


        public void RecFolder( DirectoryInfo dirInfo )
        {
            var tasks = new List<Task>( );

            foreach ( var dir in dirInfo.EnumerateDirectories( ) )
            {
                var task = Task.Factory.StartNew( ( ) => RecFolder( dir ) );
                tasks.Add( task );
            }

            Task.WaitAll( tasks.ToArray( ) );
        }

Meine Probleme nun:*Laut Profiler brauche ich 90% der Zeit für Task.Waitall(). Wie vermeide ich das? *Es gibt ein Ende, ich weiß nur nicht wann. Daher kann ich keine BlockingCollection verwenden, oder? *Die SyncQueue hier kenne ich. Entspricht aber nicht meinen Vorstellungen.

Danke, Hans18

05.02.2013 - 12:18 Uhr

Die aktuelle Tabelle hat 3 Spalten.
S1 => NUMBER
S2 => NUMBER(10,8)
S3 => NUMBER(10,8)

😃

05.02.2013 - 09:57 Uhr

Kann ich mir den generierten CommandText + Parameter anzeigen lassen, der an den Server gesendet wird?

05.02.2013 - 08:28 Uhr

Laos mit Integer funktioniert das bei mir auch super, aber mit Decimal NUMBER(10,8) nicht. Oder ich hab einen anderen Fehler.
Aber dass Add() nur String erkennt glaube ich langsam doch auch nicht mehr. Denke das war eine Fehlinfo auf Oracle bezogen.

04.02.2013 - 17:57 Uhr

Es funktioniert, wenn ich mit einem OracleParameter, dem jeweiligen Typ und Größe arbeite.
Und ja, Oracle arbeitet intern nur mit Decimal und deswegen liefert laut Doku ExecuteScalar auch ein Decimal. Dass Add() den Typ nicht erkennt finde ich schwach; konnte ich aber so in der Deutlichkeit auch nirgendwo finden.
AddWithValue gibt es beim ODP.NET nicht 🙄

04.02.2013 - 14:16 Uhr

Office Paket auf dem Server installiert?
Ich bezweifel, dass Domainbox bei ihren Webhosting-Paketen Office bereit stellt...

04.02.2013 - 13:51 Uhr

verwendetes Datenbanksystem: Oracle 64Bit + ODP.NET

Hallo zusammen,

ich habe eine Oracle-Datenbank, die ich mit Daten speisen soll.
Die Daten erhalte ich per Stream und die Umwandlung findet bei mir statt.

Die aktuelle Tabelle hat 3 Spalten.
S1 => NUMBER
S2 => NUMBER(10,8)
S3 => NUMBER(10,8)

Die C# Seite arbeitet für alle 3 Spalten mit Decimal (ist doch richtig, oder?).
Die Anfrage sieht wie folgt aus:

       const string stat = "SELECT COUNT(*) FROM STATIONS WHERE S1= :S1";

                using (var oC= new OracleCommand(stat,con))
                {
                    oC.Parameters.Add("S1", e.S1);
                    return (Decimal)oC.ExecuteScalar();
                }

Jedoch erhalte ich immer die Fehlermeldung: ['System.Exception'(Die angegebene Umwandlung ist ungültig.)]]

Woran kann das noch liegen?