Laden...
D
dannyyy
myCSharp.de - Member
26
Themen
62
Beiträge
Letzte Aktivität
vor 14 Jahren
Dabei seit
13.07.2004
Alter
39
Herkunft
Zürich
Website
Blog
Erstellt vor 14 Jahren

Benutzen bei uns:

* CruiseControl.NET: automatische Builds (Zeit und andere Trigger), Staging, Tests, ...
* MSTest: Für die Unit-Tests
* Sharepoint: Für Tickets, Task, Bug-Tracking, Wiki, ...
* MSBuild zusammen mit CCnet fürs Builden
* Und die CodeCoverage Tools von VS für Metriken und CodeCoverage
* SVN als Code-Repository

Sind soweit zufrieden mit dieser Konstellation. CCnet macht alles was wir wollen, benötigt aber einiges an Zeit bis alles Konfiguriert ist.

Erstellt vor 16 Jahren

Guten Tag,

Ich bin auf der suche nach einem Algorithmus / Pattern um folgendes Problem zu lösen:

  • Es gibt einen zentralen Datastore, der Datensätze enthält die einen Status von 0-2 haben.
    0 = Nicht erledigt
    1 = In bearbeitung
    2 = Erledigt

  • Eine oder mehrere Instanzen eines Verarbeitungsprogrammes, welche auf den selben Datenstore zugreifen.
    Die Instanzen kennen sich untereinander nicht! Weder Anzahl noch direkte Kommunikationsmöglichkeit.

Nun gibt es folgenden funktionierenden Ablauf:

  • Jede Instanz holt sich vom Datenstore eine Menge von Datensätzen die den Status 0 haben und setzt diesen auf 1 (atomar).
  • Verarbeitet die Datensätze und setzt bei jedem verarbeiteten den Status 2.
  • Die Datensätze werden in einer PriorityQueue in der Instanz verwaltet.

Das Problem was nun gelöst werden muss ist folgendes: Wie kann bei einer abgestürzten Queue detektiert werden, welche Datensätze noch in der Queue waren mit dem Status 1
und somit noch nicht abgearbeitet wurden.

Zwei mögliche Ansätze die dabei in Frage kommen sind:

  • Alle vorhandenen Instanzen leeren ihre Queues und bauen Sie neu auf in dem Status mit 0 und 1 berücksichtigt werden
    (Setzt voraus, dass alle Instanzen vom Absturtz der Queue erfahren haben und garantiert ihre Queues leeren)
  • Es werden nur jene mit Status 1 neu zugeteilt, die vorhin von einer abgestürzten Queue nicht mehr verarbeitet wurden
    (Setzt voraus, dass zu jedem Datensatz bekannt ist, wer diese in seiner Queue hat)

Wie kann dies bewerkstelligt werden, ohne dass bekannt ist wieviele Instanzen zur Zeit laufen und diese Untereinander kommunizieren könnten.
Einzige Kommunikation die möglich ist, ist eine Tabelle in der gemeinsamen Datenbank (Datastore) zu benutzen um eine resync. anzuzeigen.

Besten Dank für jeden lösungsbringenden Vorschlag
Freundliche Grüsse
Danny Meier

Erstellt vor 16 Jahren

1 In der produktiven Umgebung wird sich Dispatched immer 0/1 sein.
Beim Mailcode wird es wohl +/- 10 verschiedene geben und das Datum wir immer anders sein. Wo wäre es sinnvoll einen Index zu setzten und wo nicht?
Das WHERE Kriterium wird auch im produktiven Teil so bleiben (dies drei genannten)

  1. Kleine Erklärung wieso die Transaktionen / Locks so gewählt wurden.
    Mehrere Controller-Threads (ca. 2-8) übernehmen die Aufgabe den nächsten unbearbeiteten Datensatz zu holen (soll heissen, nur die Zeile Locken und auf Dispatched = 1 zu setzten), der Datensatz wird für die effektive Verarbeitung an einen Worker-Thread im ThreadPool übergeben (dieser Teil funktioniert sehr gut und Performant). Daher ist es wichtig, das die Controller Thread sich nicht schneiden, resp. gelockte Datensätze mit Readpast übersprungen werden.

Wie kann dieser Teil optimiert werden? Sehe zur Zeit keinen anderen Weg als mit Locks und Transaktionen zu arbeiten. Die Controller laufen permanent also nicht einfach eine verarbeitung mit alles gelesen oder so.

EDIT:
Ich habe 25'000 Einträge generiert mit Dispatched = 0!
Danach 4 mal obiges Programm laufen laufen --> Resultat:


0 / 25'000 bereits verarbeitet
00:00:12.1838645

5'000 / 25'000 bereits verarbeitet
00:00:22.0532166

10'000 / 25'000 bereits verarbeitet
00:00:36.9791626

15'000 / 25'000 bereits verarbeitet
00:00:53.4077915

Komisch finde ich, das bei jedem Durchlauf die Zeit massiv höher wird.

Erstellt vor 16 Jahren

Guten Tag,

Zur Zeit habe ich mit einem Problem zu kämpfen, welches für mich nicht ganz nachvollziehbar ist.

Verwendet wird MSSQL 2008 Enterprise als DBMS.

Mein Problem ist, dass mit jeder Abfrage die ich tätige, die Verarbeitung länger dauert und immer mehr in Performance Probleme laufe.

Die Tabelle sieht in etwa so aus:


CREATE TABLE Message ( 
	MessageId bigint identity(0,1)  NOT NULL,
	Guid char(32) NOT NULL,
	SenderName varchar(50) NULL,
	SenderEmail varchar(255) NOT NULL,
	Applicationcode varchar(10) NOT NULL,
	Mailtype varchar(10) NOT NULL,
	Reference varchar(50) NULL,
	Dispatched bit NOT NULL,
	ScheduledDispatch datetime NOT NULL,
	CreateDate datetime NOT NULL,
	DispatchDate datetime NULL,
	DeleteDate datetime NULL,
	Signed bit NOT NULL,
	Subject varchar(255) NOT NULL
);

Ein Index wurde auf die drei Felder Dispatched, ScheduledDispatch und Mailtyp gelegt. Probehalber, eimal als einzelnen Index pro Feld und einmal einen über alle drei hinweg.

Der Workflow welcher Probleme bereitet wie folgt:

  1. Abfragen eines Datensatzes (Im Code wird kein * verwendet! Führt aber zum selben Resultat, daher hier die vereinfachte Schreibweise)

SELECT TOP 1 * 
FROM Message WITH (UPDLOCK, ROWLOCK, READPAST) 
WHERE Dispatched = 0 AND Mailtype = 'PLAIN' AND ScheduledDispatch <= '2009-03-24';

  1. Sobald ich das Resultat habe, aktualisiere ich in der selben geöffneten Transaktion den Datensatz damit Dispatched = 1 wird.

Es wurden verschiedene Tests gemacht. Zum einen 5000 Einträge generiert, danach Zeit gemessen um 5000 Einträge auszulesen und zu updaten. Danach weitere 5000 generiert und wieder ausgelesen und geupdated.
Mit jeder weiteren Abfrage (und weiteren 5000 Einträgen) verlängert sich der ganze Prozess um 15-20s!!
Ein anderer Test ist 25'000 Einträge generieren und danach immer 5000 verabreiten (abfrage und updaten) und Zeit anzeigen lassen. Danach die nächsten 5000 in Angriff nehmen. Auch hier, mit jedem weiteren durchlauf erhöht sich die Zeit um 15-20s.

Woran kann das liegen? Wo liegt der Fehler?

Folgender Code wurde zum Testen verwendet. Hier ist mit Absicht kein Excpetion-Handling etc. vorhanden! Nicht das es den wirklichen Programmierstil währe 😉 Auch ist im produktiven Code SqlParameter etc. vorhanden. Und keine anfälligen String-Konkatenationen.


    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();

            SqlConnection conn = new SqlConnection(@"Data Source=LOCALHOST\SQL2008;Initial Catalog=SMTP_MAILER_DB_TEST;Integrated Security=SSPI;");
            conn.Open();


            for (int i = 0; i < 5000; i++)
            {
                SqlTransaction trans = conn.BeginTransaction();
                SqlCommand select =
                    new SqlCommand(
                        "SELECT TOP 1 MessageId FROM Message WITH (UPDLOCK, ROWLOCK, READPAST) WHERE Dispatched = 0 AND Mailtype = 'PLAIN' AND ScheduledDispatch <= '2009-03-24';",conn);
                select.Transaction = trans;
                SqlDataReader reader = select.ExecuteReader(CommandBehavior.SingleResult);
                reader.Read();
                if (reader.IsDBNull(0))
                    continue;
                SqlCommand update =
                    new SqlCommand(string.Format("UPDATE Message SET Dispatched = 1 WHERE MessageId={0};",
                                                 reader.GetInt64(0)),conn);
                reader.Close();
                update.Transaction = trans;
                update.ExecuteNonQuery();
                trans.Commit();
            }

            conn.Close();

            sw.Stop();
            Console.WriteLine(sw.Elapsed);
        }
    }

Bin um jeden Tipp dankbar.

Gruss Danny

Erstellt vor 16 Jahren

Das Entity-Framework kann die Vererbung mittels den drei gebräuchlichen Patterns abbilden. Für meinen Zweck eignet sich das Table-per-Type am besten.

Ein Problem das ich aber habe ist wie ich mit der Parallelität umgehen soll beim Update-Prozess. Die einzige Möglichkeit die Paralellität gestützt durch das Framework zu handhaben ist das setzten des Concurrency-Flag auf fixed. Ist das wirklich die einzige Option? Bei LinqToSql gibts ja verschiedene Lösungen angefangen bei einer Row welche als Version (timestamp) definiert ist, bis zur Möglichkeit beim Attachen jeweils original und geändertes Objekt mitzugeben.

Wenn ich nun beim Basistyp wie auch beim geerbten typ einige Spalten auf fixed setzte erhalte ich eine Exception die mir mitteilt, dass dies nicht möglich ist für abgeleitete Typen. Gibt es da eine gescheite Lösung dazu?

Und gibt es wirklich keine Möglichkeit eine ganze Entität/Klasse als Fixed zu markieren ohne dies für X Attribute einzeln zu erledigen?

Welche Ansätze verfolgt ihr für Optimistic Concurrency?

Es handelt sich schlussendlich um eine Webanwendung...oder lässt ihr die Parallelität aussenvor beim updaten von Datensätzen?

Vielen Dank und Gruss
Danny

Erstellt vor 16 Jahren

Hallo,

Ich möchte gerne mal ein paar Meinungen höhren bzüglich dem einsetzten des neuen ASP.NET MVC Frameworks bei einem neuen kommerziellen Projekt.

Mir ist bekannt, dass es zur Zeit "noch" Beta ist. Genau hier stellen sich bei mir verschiedene Fragen:*Wird es definitiv eine Final Version geben des MVC-Frameworks oder ist dies bei einem Beta Stadium noch nicht garantiert? *Das Änderungen in der API folgen werden ist nichts neues und im Masse durchaus zu verkfragen, sofern aber die Prinzipien und Life-Cyles in etwa so stehen bleiben. Kann man sich auf keine all zu grosse Veränderungen mehr verlassen? *Würdet ihr generell auf ein Beta Framework setzen? Resp sehr ihr grosse negative Aspekte, welche einen kommerziellen Einsatz noch nicht zulassen? (Funktional, ...)

Ich für meinen Teil habe bereits zwei Projekte im schulischen und privaten Bereich damit umgesetzt und abgesehen von der fehlenden Dokumentation als durchaus gut befunden. Daher würde mein Bauchgefühl zu ja tendieren.

Vielen Dank für eure zahlreichen Antworten.
Grüsse Danny

Erstellt vor 16 Jahren

Vielen Dank, genau so eine Library habe ich gesucht.
Für meinen Zweck genau ausreichend. Wobei die Qualität der Ausgabe noch etwas höher sein könnte. Erreiche da mit Tools wesentlich bessere Qualität, ermöglichen mir aber auch hunderttauschen einstellungen.

Sollte noch jemand eine ähnliche Bibliothek kennen, werde ich mir diese gerne auch anschauen. Ansonsten kann der Thread bei gelegenheit geschlossen werden.

Gruss Danny

Erstellt vor 16 Jahren

Hallo,

Habe zu meinem Anliegen bereits Google wie auch die Forensuche bemüht, leider aber nichts zufriedenstellendes gefunden.

Gibt es ein Framework/Library in .NET welche es mir erlaubt Konvertierung an Videomaterial durchzuführen?
Hintergrund meiner Frage ist, dass mein MP3-Player kein MP4 abspielen will. Jetzt aber alle Podcasts von Hand zu konvertieren wird mir auf die Dauer zu mühsam. Daher will ich mir eine kleine App schreiben die fortlaufend meine Podcasts synchronisiert und diese auch in das Wunschformat umwandelt.

Neben dem ändern des Containers muss auch das skalieren des Bildmaterials wie auch der Bitraten, Fps etc möglich sein.

Eines der bekanntesten OpenSouce Projekte in dieser Hinsicht ist sicher ffdshow oder mencode. Wobei kein Interface anbieten, dass ich auf anhieb benutzen könnte, oder irre ich mich da?
Alternativ wäre ich auch mit einer Lösung zufrieden die eine externe .exe aufruft, welche die Konvertierung dann vornimmt. Aber auch hier habe ich bisher nur möglichkeiten gefunden über Umwege und keine direkte MP4->Xvid.

Vielen Dank für eure Hilfe und Informationen
Gruss Danny

Erstellt vor 16 Jahren

Hallo,

Ich suche nach einer Library zum erzeugen von Charts, die anhand von vielen X, Y Koordinaten darstellen können, in welchen Bereichen viele Punkte vorhanden sind und wo wenige. Am schönsten wäre es, wenn sich das ganze mit einer Grafik unterlegen lässt, wie das beigefügte Beispiel zeigt. (Wurde händisch in einem Grafikprogramm gezeichnet).

Natürlich bin auch auch offen gegenüber anderen Darstellungsmöglichkeiten (3d?) die solche Hotspots hervorheben können.

siehe Anhang

Oder wie aufwändig wäre es so etwas selbst zu realisieren? Wie man zeichnet weiss ich. Die Frage ist mehr, welche Algorithmen ich verwenden soll/muss damit solche Punkkonzentrationen ersichtlich werden.

Vielen Dank
Gruss Danny

PS: Wie nennt man diese Art von Charts? Vielleicht habe ich deswegen nicht viel beim Suchen gefunden.

Erstellt vor 16 Jahren

So hab mich vorhin dem ganzen nochmals angenommen und entsprechend kam mir dann auch die zur Lösung führende Idee.


        private void CreateChart(string uid, string name)
        {
            //zedGraphControl1.GraphPane = new GraphPane();
            GraphPane myPane = zedGraphControl1.GraphPane;

            myPane.Title.Text = "Active periods during the day of " + name;
            myPane.XAxis.Title.Text = "Today";
            myPane.YAxis.Title.Text = "Active";
            myPane.Chart.Fill = new Fill(Color.White, Color.Yellow, 75F);

            PointPairList list = new PointPairList();
            using (YfotDataContext ctx = new YfotDataContext())
            {
                var query = from i in ctx.YfotUsers
                            where i.uid == uid && (i.sessionStartTime.Date == DateTime.Today.Date)
                            orderby i.sessionStartTime ascending
                            select i;

                foreach (var session in query)
                {
                    list.Add(new XDate(session.sessionStartTime.AddMilliseconds(-1)), 0);
                    list.Add(new XDate(session.sessionStartTime), 1);
                    list.Add(new XDate(session.sessionEndTime), 1);
                    list.Add(new XDate(session.sessionEndTime.AddMilliseconds(1)), 0);
                }
            }

            myPane.CurveList.Clear();
            LineItem myCurve = myPane.AddCurve("", list, Color.Black, SymbolType.None);
            myCurve.Line.Fill = new Fill(Color.Yellow, Color.OrangeRed, Color.Red, 30F);

            myPane.XAxis.Type = AxisType.Date;
            myPane.YAxis.Scale.Min = 0.0;
            myPane.YAxis.Scale.Max = 2.0;
            myPane.YAxis.Scale.MinorStep = 1.0;
            myPane.YAxis.Scale.MajorStep = 1.0;
            myPane.XAxis.Scale.Min = new XDate(
                DateTime.Today.Year,
                DateTime.Today.Month,
                DateTime.Today.Day,
                0,
                0,
                0);
            myPane.XAxis.Scale.Max = new XDate(
                DateTime.Today.Year,
                DateTime.Today.Month,
                DateTime.Today.Day,
                24,
                0,
                0);

            zedGraphControl1.AxisChange();
            zedGraphControl1.Refresh();
        }