Laden...
Avatar #avatar-3206.png
Benutzerbeschreibung
„Morgen ist noch nicht gekommen, und gestern ist vorbei. Wir leben heute.”

Forenbeiträge von malignate Ingesamt 742 Beiträge

05.05.2014 - 22:00 Uhr

Hast du mal verschiedene Cultures durchprobiert?

28.04.2014 - 12:15 Uhr

Hallo,

das Auslagern von Controllern ist wirklich relativ nervig, da afaik das Discovery von Controllern auf die Hauptassembly beschränkt ist.

Ich packe mittlerweile die UI-Komponenten relative nahe beieinander (View + ViewModels + Controllers). Kann man mit Areas machen, wenn man möchte, mus man aber nicht unbedingt. Ich hatte keine Lust mehr auf das ewige rumgescrolle im Solution-Explorer 😉

Sonst hat Abt ja schon alles gesagt, je nachdem kann man noch einen Domain-Layer mit Business-Logik dazwischenschalten. In manchen Tutorialwird das Services genannt.

28.04.2014 - 09:06 Uhr

Danke, perfekt Schlussatz 😃

Edit: Ich muss doch noch kurz erwähnen, dass ich seit November fast wöchentlich darauf hoffe, dass MongoDB endlich Asynchronität unterstützt 😉

28.04.2014 - 07:50 Uhr

Hallo Abt,

das sind so viele einzelne Themen, deshalb Liste ich hier meine Anworten einfach mal auf:

@Skalierung: Du hast absolut recht, es kommt auf das Szenario an, ich mache aber mal ein Beispiel: Bei Busliniensuche machen wir tlw. bis zu 50 externe Requests pro Suchanfrage, die im Mittel vll. 250ms dauern. Die Anzahl Threads pro Core sind im IIS 50, bei einem QuadCore hätte ich also 200 Threads zur Verfügung. Würde ich die Aufrufe mit einem Task-Wrapper parallel durchführen könnte ich pro Sekunde nur 15 Suchanfragen durchführen, mit einer asynchronen Implementierung, welche die asynchronen Http-Methoden nutzt bin ich nur durch meine Netzwerkanbindung, die externe Resource und die Anzahl der Http-Verbindungen begrenzt, die das Betriebssystem erstellen kann. Ein Extrem-Beispiel ist hier Node.js, da meines Wissens nach Node Single-Threaded ist und die Skalierung alleine durch "echte" Asynchronität erreicht wird.

@Azure-Tutorial: Async und Tasks haben doch keinen direkten Zusammenhang mit Thread-Pools, ich würde 20€ darauf wetten, dass die Client-Methoden für Queues und so weiter intern die asynchronen Http-Methoden verwenden.

@Framework: Ich habe gestern noch genauer nachgeschaut und ich konnte kaum Beispiele für solche Wrapper im Framework finden. Insbesonder auch nur dann, wo Interfaces oder abstrakte Klassen implementiert werden müssen, z.B. MemoryStream oder StringReader.

@Sortierung: Das ist nicht korrekt, man kann bei großen Datenmengen mit Parallelität durch Tasks sehr gut eine Performance-Verbesserung erreichen, die mit der Anzahl an Prozessoren steigt. ich weiß gar nicht mehr, wie viele Implementierungen für 1D und 2D-Sortierungen ich während des Studiums mit Java und C# gemacht habe und damit immer die Standard-Implementierungen deutlich geschlagen.

@MongoDb: Es kommt ja auf die Anzahl der parallelen Anfagen pro User-Request an und darauf wieviele Millisekunden eien Anfrage dauert. Da wahrscheinlich ein Query nur 20 oder 30ms dauert und du nicht 200 parallele Anfragen pro Benutzer machst, kann ich mir gut vorstellen, dass du von einem Wrapper profitierst. Das trifft aber nicht auf jedes Szenario zu, weshalb es keine gute Idee wäre, die Wrapper in den Mongo-Treiber zu packen. (Ein solcher Vorschlag wurde ja auch schon im Mongo-Jira gemacht).

Wie in meiner letzten Antwort gesagt: Ich habe nichts generell gegen Wrapper-Methoden. Da aber je nach Szenario die Implementierung extrem wichtig ist und ich ja von außen nicht erkenne, wie sie funktioniert, sollte man vll. über eine differenziertere Namensgebung nachdenken. Das wird umso wichtiger, wenn die Ausführungszeit der Methode steigt.

BTW: Ich würde im Zusammenhang mit Asynchronität nicht von Warten reden. Da wartet nämlich niemand, das ist nämlich genau der wichtige Unterschied. Bei asynchronen Methoden wird der SynchronizationContext verwendet, der nach erfolgreicher Ausführung mehr oder weniger eine Methode mit dem Code zur weiteren Ausführung in die Dispatcher-Queue einreiht, die dann von der Programmhauptschleife ausgeführt wird (Desktop) oder in die ThreadPool-Queue (Web).

27.04.2014 - 10:42 Uhr

Ich würde so einen Wrapper sogar selber verwenden, zum Beispiel in einer Desktop-Anwendung, das Problem ist, dass ich ja von außen nicht unterscheiden, kann, wie die Methode intern arbeitet. Deshalb würde ich mich an die "Konvention" halten (die ich bisher im .NET Framework und anderen Bibliotheken so sehe), dass Async-Methoden "Task XXXAsync(...)" für externe Nebenläufigkeit sind. Ich habe nichts dagegen, wenn jemand Wrapper anbietet, aber dann sollte man die auch irgendwie anderst nennen.

26.04.2014 - 10:32 Uhr

Hallo herbivore,

es ist wichtig, dass es hier um eine eigene Library geht, meine Pauschalisierung trifft für Anwendungen nicht zu.

Ich finde die Unterscheidung zwischen Asynchronität und Parallelität auch extrem schwierig, vielleicht ist es im Englischen besser, aber im Deutschen klingt beides ziemlich gleich, nämlich, dass ich irgendwas nebenläufig mache. Deshalb versuche ich mal eine andere Definition mit neuen Begriffen, weil die deutlicher macht, was man erreichen möchte:

  1. Externe Nebenläufigkeit werden verwendet, wenn man eine Aufgabe an ein anderes System delegiert, Beispiele dafür:
  • Ein anderer Server führt eine Anfrage aus
  • Ein anderer Prozess bearbeitet meine Anfrage
  • Die Datenbank führt eine Abfrage aus
  • Das IO-System liest einen Block von der Festplatte
  1. Interne nebenläufige Methoden behalten die Kontrolle und führen Dinge parallel aus. Das muss nicht nur CPU-lastig sein, sondern kann natürlich auch IO-Anfragen enthalten. Hier sind die Anteile aber extrem wichtig. Wenn man beispielsweise 10 parallele Anfragen an einen externen Server hat und vor jeder Anfrage Berechnungen mit 1ms ausführt, sollte man sich zweimal überlegen, ob man nicht lieber ohne Thread-Parallelität, sondern mit asynchronen Methoden arbeitet.

Allgemein ist async-await ja nur ein schönerer Synchronizationsmechanismus für Callbacks, das Problem ist aber, dass typischerweise asynchrone Methoden für externe Nebenläufigkeit verwendet werden. Wenn mir jetzt jemand in einer API eine asynchrone Methode bietet, gehe ich auch davon aus. Verwende ich diese Methode mit falschen Annahmen kann ich genau das Gegenteil erreichen, was ich erreichen möchte, z.B. in Server-Anwendungen die unnötige Belegung von Threads und schlechtere Skalierbarkeit. Deshalb finde ich es eine schlechte Idee in APIs synchrone Methoden zu Wrappen. Wenn ich irgendwo Nebenläufigkeit brauche, sollte man es außerhalb der API machen, hier kann ich dann auch innerhalb eines Tasks mehrere synchrone IO-Methoden aneinander hängen.
Es hält mich natürlich nichts davon ab, zur Performance-Optimierung Tasks zu verwenden, (beispiel Sortierung), dann ist die Methode aber nach außen weiterhin synchron.

Deshalb hier meine Regel in der Kurzfassung: **Stelle in APIs nur Async-Methoden für externe Nebenläufigkeit bereit. **

Die Verwendung von async und Tasks in einer Anwendung ist natürlich abhängig von der Situation.

26.04.2014 - 00:01 Uhr

Ich muss das einfach noch mal wiederholen, weil das so oft falsch gemacht wird:

Man muss hier zwischen Asynchronität und Parallelität unterscheiden.

  1. Async: Asynchroner Code ist IO-Bound und delegiert die Aufgabe an einen externe Ausführungseinheit, z.B. Hardware, einen anderen Prozess oder ein komplett anderes System und fahrt dann mit der Ausführung der eigenen Antwort fort, ohne, sobald das Ergebnis da ist. Das hat den Vorteil, dass der aktuelle Thread nicht blockiert wird, der dann gleichzeitig andere Dinge erledigen kann:
  • In einer Desktop-Anwendung blockiert die UI nicht, der UI-Thread kann weiter Animationen ablaufen lassen und auf Interaktion reagieren.
  • In einer Server-Anwendung kann der Thread weitere Requests entgegen nehmen, bis er auf die asynchrone Antwort reagieren muss.
  1. Parallel: Paraleller Code erstellt neue Threads um CPU-lastige Algorithmen zu beschleunigen oder Dinge nebenläufig auszuführen.

Auf Basis dieser Definitionen würde ich folgende Best-Practices:

  1. Wenn du etwas IO-lastiges hast, implementiere zuerst die asynchrone Methode und schreibe dann darauf aufbauen eine synchrone Methode, wie du es gemacht hast. Du kannst aus einer synchronen Methode keine asynchrone Methoden machen, sondern nur eine parallele.

  2. Schreibst du ein Framework, verwende Tasks nur dann, wenn du einen CPU-lastigen Algorithmus wesentlich beschleunigen kannst, z.B. ein Sortierungalgorithmus. Es ist keine gute Idee, eine Task-Wrapper-Methdode für eine synchrone Methoden anzubieten, weil die Methode dann asynchron aussieht, obwohl sie es gar nicht ist. Außerdem ist der Overhead je nachdem riesig.

  3. Verwende keine parallen Task in Server-Anwendung, es sei denn du bist dir wirklich sicher. Es blockiert Thread, die bessere Antwortzeit geht auf Kosten de Skalierbarkeit.

@Abt: Diese Directory-Methoden sind meiner Meinung nach eine üble Idee, das gaukelt Asynchronität vor, die gar nicht vorhanden ist.

14.04.2014 - 11:35 Uhr

Danke, noch nicht. Der folgende Blog-Post scheint das ganz gut zusammenzufassen:

http://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/

14.04.2014 - 11:15 Uhr

Es beantwortet nicht meine Frage und ich weiß auch nicht genau, auf was du hinauswillst.

Im Prinzip ist das doch kein Performance-Problem. Man liest den Type-Parameter aus der Route holt sich per Dictionary den passenden Typ und erstellt dann den Controller. Das ganze kann man noch per IL-Generierung beschleunigen, wenn man möchte:

Fast version of the Activator.CreateInstance method using IL

Ich bin sicher, dass sich das maximal im einstelligen Millisekunden-Bereich bewegt, wenn überhaupt. Das ist es mir allemal wert, zumal ich in meinem Szenario eh keine Wahl habe, wenn ich einigermaßen wartbare und erweiterbare Software haben möchte. Ich würde sagen das fällt hier schon unter Premature Optimization.

14.04.2014 - 09:54 Uhr

Hallo zusammen,

ich habe mehrere Plugins, die ihre Metadaten in einer Registry bekannt machen und würde für diese gerne generische Controller verwenden. Der Typ des Plugins soll dabei Teil der Url sein:

z.B. // POST: /plugins/{name}/

In MVC gibts dafür die Controller-Factory, in Web-Api finde ich aber keine analoge Klasse / Interface.

Hat jemand eine Idee, wie man das am besten realisiert? Eigene Route vielleicht?

10.04.2014 - 10:51 Uhr

Der Header ist mir noch zu groß, mach die hellblaue Leiste weg und pack das Logo links in den dunkelblauen Streifen.

Außerdem ist mir das Zoomen im Klassendiagram noch negativ aufgefallen. Hier wäre es besser, wenn es meine Maus-Position als "Zentrum" benutzt.

08.04.2014 - 08:36 Uhr

Lass doch mal diese ganzen Präfixe weg, das steht doch direkt da, dass es ein int ist und dann wähle bessere Namen. Des weiteren musst du deine Koordinaten in das lokale Koordinatensystem deines Sprites umrechnen:


private bool AlphaTest(Texture2D texture, int spriteX, int spriteY, int spriteWidth, int spriteHeight, int mouseX, int mouseY)
{
    uint color = 0;
    
    int localX = mouseX - spriteX;
    int localY = mouseY - spriteY;

    if (localX > 0 && localY > 0 && localX < spriteWidth && localY < spriteHeight)
    {
        uint[] textureData = new uint[1];
        
        Texture.GetData<uint>(0, new Rectangle(localX, localY, 1, 1), textureData, 0, 1);

        color = textureData[0];
    }

    return color != 0;
}

01.04.2014 - 16:56 Uhr

Sind das die Credentials des Proxies oder der finalen Zielseite? Wenn ersteres der Fall ist, solltest du die Credentials direkt im WebProxy Objekt setzen.

20.03.2014 - 19:58 Uhr

Ja, passt, hatte das früher auch mal mit Erhöhung der Ports in der Registry gelöst, das geht bei Azure-Websites leider nicht. Bisher ist der Fehler auch noch nicht erneut aufgetreten, also hoffe ich mal, dass es so bleibt. Alternativ werde ich dann nochmal testen, ob vll. viele kleine Instanzen besser sind.

20.03.2014 - 19:56 Uhr

Ich erwarte ja keine 100% Stabilität, sondern suche eher eine Liste von Standard-Szenarien, die man gut im Repository behandeln könnte. Die EndOfStreamException ist bestimmt eine davon (aber auch nicht für alle Fälle natürlich, beim Lesen von Logs etc. würde ich es einfach ignorieren und den Admin nochmal versuchen lassen).

20.03.2014 - 19:51 Uhr

Hi, seit unserem Umzug auf Azure bekomme ich regelmäßig die folgende Fehlermeldung:

"Stream was not readable"

Die Fehler tauchen immer gehäuft auf, also z.B. 20 zur gleichen Sekunde und dann wieder 1Stunde lang gar nicht. Sie treten in folgendem (gekürzten) Code-Segment auf, an der Stelle, an welche der StreamReader erstellt wird. Ich finde absolut nichts im Netz dazu. Ich kann mir vorstellen, dass es irgendwelche eigenartigen Protokoll-Error sind, evtl. kann man einfach den Request wiederholen. Ich bin mir aber nicht sicher. Auch hier ist es wieder sehr nervig, dass es so viele verschiedene Fehler gibt: IOException, ArgumentException, SocketException, EndOfStreamException, WebException. Da wäre es super, wenn es irgendwo eine Liste gäbe, was die zu bedeuten habe, damit man sich entscheiden kann, wie man welche abfängt. Im Moment lerne ich gefühlt jeden Tag eine neue Meldung.


private static async Task<string> ReadAsync(Encoding encoding, HttpWebRequest httpRequest)
{
	string webContent = null;

	WebException exception = null;
	WebResponse response = null;
	try
	{
		response = await httpRequest.GetResponseWithTimeoutAsync();

		Stream responseStream = response.GetResponseStream();
		try
		{
			using (StreamReader reader = new StreamReader(responseStream, encoding))
			{
				responseStream = null;

				webContent = await reader.ReadToEndAsync();
			}
		}
		finally
		{
			if (responseStream != null)
			{
				responseStream.Dispose();
				responseStream = null;
			}
		}
	}
	finally
	{
		if (response != null)
		{
			response.Close();
		}
	}

	return webContent;
}        

private static Task<WebResponse> GetResponseWithTimeoutAsync(this WebRequest request)
{
	if (request == null)
	{
		throw new ArgumentNullException("request");
	}

	RequestState requestState = new RequestState { Request = request };

	IAsyncResult asyncResult = request.BeginGetResponse(HandleResponse, requestState);

	if (!asyncResult.IsCompleted && request.Timeout != Timeout.Infinite)
	{
		ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, HandleTimeout, requestState, request.Timeout, true);
	}

	return requestState.CompletionSource.Task;
}

private static void HandleTimeout(object result, bool timedOut)
{
	RequestState localState = (RequestState)result;

	if (timedOut)
	{
		localState.Timeout = true;
		localState.Request.Abort();
	}
}

private static void HandleResponse(IAsyncResult result)
{
	RequestState localState = (RequestState)result.AsyncState;

	try
	{
		localState.CompletionSource.TrySetResult(localState.Request.EndGetResponse(result));
	}
	catch (WebException ex)
	{
		if (localState.Timeout)
		{
			localState.CompletionSource.TrySetException(new WebException("No response was received during the time-out period for a request.", WebExceptionStatus.Timeout));
		}
		else
		{
			localState.CompletionSource.TrySetException(ex);
		}
	}
	catch (Exception ex)
	{
		localState.CompletionSource.TrySetException(ex);
	}
}

20.03.2014 - 19:18 Uhr

verwendetes Datenbanksystem: MongoDB

Hi,

ich lerne gerade, dass der MongoDB-Treiber doch viele Situationen nicht automatisch behandeln kann. Neulich zum Beispiel hat sich der Primary verabschiedet und ein paar Anfragen haben sich mit

System.IO.EndOfStreamException: Attempted to read past the end of the stream.

verabschiedet. Nicht weiter tragisch, aber ich hätte doch gerne ein bisschen mehr Stabilität. Immer mehrere Versuche durchzuführen, könnte aber in manchen Situationen kontraproduktiv sein. Es wäre also sinnvoll die Anwendungsfälle genau zu unterscheiden. Benutzer hier jemand MongoDb und wenn ja, habt ihr Mechanismen um mit solchen Fehlern umzugehen?

VG,
Sebastian

19.03.2014 - 13:57 Uhr

Habe ich versucht, geht leider Ewigkeiten 😉. Sind dann doch ein paar Millionen Kombinationen.

Was mir in dem Zusammenhang gerade nicht klar ist, ist die korrekte Verwendung der WebException. Die kann ja auch ein Response-Objekt enthalten. Ich frage mich gerade, wie das Disposed wird. Suche gerade mit ILSpy, aber sind dann doch ein paar tausend Zeilen code 😉

19.03.2014 - 13:20 Uhr

Ja, für Background-Tasks verwende ich Worker-Roles bereits. Hiere schiebe ich in Tasks in die Queue (ServerBus wäre kompfortabler, aber der Azure Scheduler kann nur Items in die Queue schieben). Aber das Problem betrifft nicht mal IIS direkt sondern die Windows TCP-Buffer, das heißt das Problem würde sich unter Umständen nur verschieben. Die Requests über die hier rede, werden pro User-Request ausgeführt (natürlich gibt es Caches, gespeicherte Zwischenwerte in Mongo und alles, aber Preise können sich leider relativ schnell ändern).

Eine Idee wäre viele kleine Instanzen zu verwenden, dann wird aber natürlich das Caching ineffektiver. Außerdem könnte es der stabilität dienen, die Anzahl an Web-Requests einfach zu beschränken.

19.03.2014 - 11:38 Uhr

Bisher habe ich daran noch gar nicht gedacht, um ehrlich zu sein. Ich bin mir aber nicht sicher, ob es das Problem nicht nur verschiebt. Wir hast du dann zwischen WebRole/Website und Worker-Role kommuniziert?

19.03.2014 - 10:32 Uhr

Hallo zusammen,

wir haben eine Suchengine, die seit neuestem auf Azure läuft. Dabei laufen 3 mittelgroße Instanzen für ca. 600.000 Benutzer im Monat (etwas überdimensioniert, ist nur zum Testen).

Wir machen sehr viele Web-Requests (ca. 200.000 pro Tag) auf externe Dienste und außerdem kommen da noch Requests für Dienste wie Caching, Tracing, MongoDb hinzu. Die Web-Requests sind in der Regel klein (< 100KB) und schnell (< 1sec). Haben immer ein Timeout zur Sicherheit von 4-10 Sekunden.

Gestern trat folgender Fehler auf: "An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full"

Ich hatte damit schonmal zu kämpfen. Bei einem Root-Server kann man in der Registry die Queue-Größe erhöhen. Das geht in meinem Fall nicht. Interessant wären andere Konzepte wie evtl. Connection-Pooling usw. Welche Maßnahmen kennt ihr für dieses Problem?

Ich habe auch schon auf SO gefragt: Azure: An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full, bisher aber ohne Erfolg. Zu dem Thema findet man auch bei Google wenig hilfreiches.

03.03.2014 - 11:56 Uhr

Das kommt natürlich auch extrem auf dein Game-Play an. Bei Age of Empires beispielweise werden die Arbeiter festen Jobs zugeordnet und verrichten dort nur Arbeiten, die in der Nähe sind.

Beispielsweise: "Baue Haus": Baue das zugewiesene Haus, suche danach die nächste Baustelle innerhalb von 10 Meter und führe "Baue Haus" aus.

Wird schwer hier eine pauschale Antwort zu geben. In vielen Spielen gibt es KI's auf mehreren Ebenen, z.B. Einheit, Gruppe, Fraktion etc.

03.03.2014 - 10:59 Uhr
  1. Präfixe weglassen
  2. Besser ausschreibe, pr = Prüfung ist unnötige Denkleistung
  3. Schreibe auch alles aus, weil du dann weniger Stress mit O/R-Mapper hast
  4. Für Datum gibts eigene Formate, oder Timestamp etc. aber auf jeden Fall kein String, sonst hast du Stress mit Sortierung usw.
  5. Was ist kl_schueid???
01.03.2014 - 18:39 Uhr

Ich will jetzt nicht gleich sagen: Vergiss es. Aber es kann sehr komplex werden.

Wenn du es versuchen willst, schau doch mal, ob du folgendes Buch noch irgendwo billiger, gebraucht bekommst: Programming an Rts Game with Direct3D

28.02.2014 - 10:22 Uhr

Hallo Herbivore,

ich weiß, hatte ich gerade noch ergänzt. Ist aber eine ziemlich schnell zu implementierende Lösung, deshalb habe ich es vorgeschlagen. Zudem ist der Speicherverbrauch ja auch nur 4x[#Vars]^2 bytes (bools werden ja, so weit ich weiß auch durch 32bit Zahlen repräsentiert) und selbst bei 1000 Variablen bist du dann erst bei vier MB, also funktioniert das bis zu einer gewissen Größe recht gut und ich kann mir sogar vorstellen, dass es bei mittleren Ausdrücken schneller ist (kommt drauf an, wie schnell der Compiler ist).

VG,
Sebastian

28.02.2014 - 10:13 Uhr

So weit ich das noch in Erinnerung habe, kann man eine Disjunktive Normalform aus einer Wahrheitstabelle leicht erstellen. Ich würde so vorgehen:

  1. A, B, C usw. durch a[0], a[1] ... ersetzen
  2. & mit && und | mit || ersetzen.
  3. Noch "a[3] =" vorne dran packen

Dann hast du aus A&(BlC) das gemacht:

a[3] = a[0] && (a[1] && a[2])

Dann hast du ein C#- Code mit a = bool-Array, dann erstellst du dynamisch eine ausführbare Funktion und erstellst alle Kombinationen aus A, B, C und führst diese Funktion aus. Dann hast du deine Wertetabelle im Prinzip fertig und musst daraus nur noch die disjunktive Normalform ableiten, was ziemlich simpel ist.

Disjunktive Normalform

EDIT: Afaik nicht die einfachste disjunktive Normalform und du bekommst schlechte Fehlermeldungen, wenn dein Ausdruck falsch ist, aber kann man in einer Stunde oder weniger umsetzen 😉. Dein Speicherverbrauch und Berechnungsdauer wächst natürlich auch exponentiell, solltest also nicht zu viele Variablen haben.

24.02.2014 - 08:52 Uhr

Das geht afaik nicht, du musst bedenken, dass viele Controls zugewiesene Werte haben, die zum Beispiel aus externen Datenquellen kommen. Die Originaldaten stehen dabei nicht mehr unbedingt zur Verfügung, um diese neu zu formatieren / übersetzen. Einfach ein Neustart erzwingen, das ist schon okay, zumal man die Sprache i.d.R. einmalig ändert.

23.02.2014 - 16:20 Uhr

Zu 4. Zumindest für das Ändern gibts die Möglichkeit, so ich habe ich das in meinem Repository früher gelöst.


private void PrepareForSaving()
        {
            foreach (DbEntityEntry entry in ChangeTracker.Entries())
            {
                ITimeTrackedEntity timeTracked = entry.Entity as ITimeTrackedEntity;

                if (timeTracked != null)
                {
                    if (entry.State == EntityState.Added)
                    {
                        timeTracked.Created = DateTime.UtcNow;
                    }

                    if (entry.State == EntityState.Added || entry.State == EntityState.Modified)
                    {
                        timeTracked.Modified = DateTime.UtcNow;
                    }
                }

                if (entry.State == EntityState.Added)
                {
                    IEntityWithGuidId guidIdEntity = entry.Entity as IEntityWithGuidId;

                    if (guidIdEntity != null)
                    {
                        guidIdEntity.Id = Guid.NewGuid();
                    }
                }
            }
        }

22.02.2014 - 12:15 Uhr

Du verwechselst hier was, du behandelst Events, willst aber zusätzlich den Zustand des Keyboards wissen. Deshalb solltest du dir noch den Keyboard Zustand speichern, z.B. so:


private HashSet<char> pressedKeys = new HashSet<char>();

private void OnKeyDown(object sender, KeyPressEventArgs e)
{
    pressedKeys.Add(e.KeyChar);

    if (pressedKeys.Contains('w') && pressedKeys.Contains('s'))
    {
         // TU WAS
    }
}

private void OnKeyUp(object sender, KeyPressEventArgs e)
{
    pressedKeys.Removed(e.KeyChar);
}

15.02.2014 - 10:47 Uhr

Also ich finde dein Vorgehen passt ganz gut, du kannst dir überlegen noch Caching auf Server-Seite einzubauen und solltest die richtigen Cache-Header setzen. Wenn der Browser das Bild nicht direkt öffnet, ist vermutlich dein Content-Type falsch. Lass mal die Leerzeichen bei JPEG weg und verwende für PNG image/png für PNG Dateien. Außerdem solltest du eine 404 liefern, wenn es das Bild mit der ID in der Datenbank nicht gibt.

31.01.2014 - 01:21 Uhr

Wir hatten hier mal mehrere hundert Icons bestellt: http://www.artistsvalley.com/xaml-icons/xaml-wpf-icons.html

Das lief ziemlich gut, wollten auch komplexe Icons wie Panzer, Sattelschlepper usw. (waren wohl eher Grafiken, aber der Übergang ist ja fließend). Kosten: ca. 30-50 €, man bekommt die Icons im Vektorformat (bei uns eben Xaml).

29.01.2014 - 09:05 Uhr

@Marius: Hast du schon ein Vorgehen für dich gefunden?

BhaaL hat schon Recht, ein Service-Locator ist eine Art Registry. Die Komponenten holen sich ihre Abhängigkeiten selbst. Die Umkehrung davon (Inversion of Control) ist Dependency Injection. Die Abhängigkeiten sind explizit über den CTOR oder Properties kenntlich gemacht und werden eben injeziert.

Wo das nicht geht, ist der Service-Locator aber noch durchaus ein gutes Muster, beispielsweise Filter in ASP.NET MVC oder jeglicher Code, bei dem die Klassen ohne Kontrollmöglichkeiten automatisch instanziiert werden müssen.

28.01.2014 - 08:28 Uhr

Der StackTrace wird ihm nicht helfen, da die Aufrufskette ja bei der Windows-Nachrichtenschleife endet. Das heißt er dürfte im StackTrace keine zwei Button-Click-Events haben.

Ich denke dir bleiben nur zwei Möglichkeiten:

  1. Du greifst in die WinAPI Trickkiste und versuchst das Click-Event zu behandeln. Hier bekommst du vll. auch ein Handle, mit dem du den Namen deines Buttons etc. bekommen kannst. Das ist aber sehr Low-Level und es ist evtl. aufwändig die User-Aktion dahinter zu ermitteln. Also Button Grid_123456 bedeutet "Löschen".

  2. Du protokollierst wirklich alles mit. Das ist jetzt vor allem nervig. Um dein Code nicht zu versauen würde ich dir PostSharp empfehlen.

27.01.2014 - 23:07 Uhr

Hi Marius,

ich schlage jetzt mal ein konkret anderes Vorgehen vor. Bei vielen oder fast schon den meisten Mustern geht es darum, verschiedene Teile voneinander zu entkoppeln. Am meisten braucht man das bei Unit-Tests. Ich würde vorschlagen, du arbeitest dich in Unit Tests und Test-Driven-Development ein und versuchst anhand einer Beispielanwendung so zu programmieren, dass die Tests möglich einfach sind. Die Tests sind einfach, wenn sie möglichst kurz sind. Für die Messung solltest du allen eigenen Code berücksichtigen, der in den Test miteinfließt, auch Helper-Methoden innerhalb deines Testes. Damit meine ich, dass Tests nicht einfach sind, wenn du zum Beispiel 100 Tests hast, die jeweils am Anfang und Ende die gleiche Methode zum Initialisieren von irgendwelchen Datenbank-Verbindungen verwendet werden. Die Gesamtkomplexität eines Tests sollte diese Methoden auch mit einschließen.

Du wirst dann wahrscheinlich bemerken, dass einfache Tests nur mit einfachem (bzw. entkoppeltem) Code möglich ist und teilweise wirst du dich echt bemühen müssen, deinen Code zu vereinfachen. Vielleicht wirst du ganz von alleine einige Patterns verwenden, die du noch gar nicht kennst. Ich bin sehr davon überzeugt, dass du damit sehr sauberen Code bekommst.

Verabschiede dich auch von dem Gedanken, ein Muster zu finden. Du wirst immer dazu lernen und jedes mal die Hände über dem Kopf zusammenschlagen, wenn du alten Code siehst. Auch wenn du bei der Entwicklung sehr sicher warst, alles richtig gemacht zu haben.

27.01.2014 - 21:08 Uhr

Das mit den Währungsreserven war mal, mittlerweile ist das eher ein Vertrauensmodell. In den USA hat sich die Geldmenge seit 2008 verdreifacht. Bei einem Wirtschaftswachsum von (ich schätze mal) +/- 0 über die ganze Zeit kann man da nicht mehr von einem Gleichgewicht reden.

24.01.2014 - 21:16 Uhr
  1. Anbieter
  • Ich habe meine eigenen Projekte noch auf Codeplex würde jetzt aber GitHub wählen
  • War von SVN und TFS bei Codeplex genervt und habe deshalb was neues gesucht. Hier habe ich meine eigenen, Closed-Source Projekte. Außerdem ist die Entwickler-Community riesig.
  • Git oder auch Mercurial
  • Irgendeine die für kommerzielle Projekte passt, da setze ich mich aber zugegeben zuwenig auseinander
  • Ich biete meine Projekte immer mit Code an, ohne ist für mich ein NoGo, siehe letzt Antwort.
  1. Entwickler
  • Kommt auf den Aufwand an. Bei Javascript nutze ich eigentlich immer Plugins, auch für kleinste Funktionen, bei .NET kommts dann wirklich auf den Aufwand an. Unter 4h code ich es immer selbst. Und natürlich, wenn es irgendwelche speziellen Anforderungen sind (Polygone vereinigen ist nicht so trivial wie man vll. denkt 😉)
  • Ich suche zu 70% direkt bei Git und sonst Google. Suche nie direkt über NuGet, das ist mir nicht transparent genug.
  • Sehe bei Suche keine große Unterschiede
  • In erster Linie Kombination aus Download-Zahlen, Bewertung und Doku (Wiki etc.), XML-Kommentare usw. sind mir recht egal, da steht meistens eh wenig hilfreiches, wenn sich die Entwickler nicht extrem anstrengen.
  • Wenn ich ein externes Projekt nehme, dann erst über NuGet, dann über DLL im lib-Folder und dann Source Code. Ich will bei externen Projekten aber immer den Quellcode haben, damit ich zur Not auch mal was fixen kann, bzw. mir bei schlechter oder unzureichender Doku selber anschauen kann, wie es funktioniert. Ausnahme: Kommerzielle Projekte (z.B. Telerik), da erwarte ich aber gute Doku und Support.
21.01.2014 - 23:48 Uhr

Du wirst nicht drum herum kommen, einen externen Provider zu verwenden, um anhand der Adresse die Geokoordinaten zu ermitteln (unbedingt Ergebnisse irgendwo speichern und wiederverwenden). Dann brauchst du nur noch die Konvertierung in das kartesiche Koordinatensystem und du musst den Nullpunkt deiner Karte kennen. Am besten du renderst die SVG-Karte als Bild vor und packst dann die Adressen drauf. Klingt jetzt nicht nach einem Hexenwerk.

21.01.2014 - 23:41 Uhr

Hi,

ich müsste die IIS Log Files anschauen und suche nach einem guten Viewer. Kennt ihr einen Log File Viewer für IIS (oder allgemein Weblogs) der auch mit großen Dateimengen klar kommt (> 10GB). Ideal wäre webbasiert, eine schöne UI und ein Sync mit einer Datenbank.

21.01.2014 - 09:05 Uhr

Ich habe mir immer Wrapper dafür geschrieben, hatte das Szenario sehr oft, da ich mal komplexere Controls für WPF geschrieben habe:


    public class ObservableCollectionWrapper<T>
    {
        private readonly ObservableCollection<T> collection;
        private readonly List<T> allItems = new List<T>();

        public ObservableCollectionWrapper(ObservableCollection<T> target)
        {
            collection = target;
            collection.CollectionChanged += collection_CollectionChanged;
        }

        private void collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                foreach (T item in allItems)
                {
                    RemoveItem(item);
                }

                allItems.Clear();
            }
            else
            {
                if (e.NewItems != null)
                {
                    foreach (T item in e.NewItems)
                    {
                        AddItem(item);

                        allItems.Add(item);
                    }
                }
                if (e.OldItems != null)
                {
                    foreach (T item in e.NewItems)
                    {
                        RemoveItem(item);

                        allItems.Remove(item);
                    }
                }
            }
        }

        private void RemoveItem(T item)
        {
            INotifyPropertyChanged propertyChanged = item as INotifyPropertyChanged;

            if (propertyChanged != null)
            {
                propertyChanged.PropertyChanged -= propertyChanged_PropertyChanged;
            }
        }

        private void AddItem(T item)
        {
            INotifyPropertyChanged propertyChanged = item as INotifyPropertyChanged;

            if (propertyChanged != null)
            {
                propertyChanged.PropertyChanged += propertyChanged_PropertyChanged;
            }
        }

        private void propertyChanged_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
        }
    }

WICHTIG: Du brauchst unbedingt eine Kopie der Liste, weil du bei einem Reset die alten Items nicht mitbekommst. Ziemlich dämlich, ist aber so.

10.01.2014 - 13:55 Uhr

Wie Abt schon gesagt hat: WCF ist für die Kommunikation zwischen ASP.NET und TCP-Server, also mit deinem obigen Begriffen dient WCF der Cmd-Weiterleitung zwischen Webserver und TCP-Server. Du solltest die Kommunikation zwischen TCP-Server und TCP-Client nicht über WCF machen, wenn du hier schon was entwickelt hast oder wenn es ein festes Protokoll gibt oder wenn die TCP-Clients SOAP nur unzureichend unterstützen.

09.01.2014 - 09:21 Uhr

Du kannst WCF doch wunderbar verwenden für die Kommunikation zwischen ASP.NET Client und TCP-Server. Ich sehe da das Problem nicht.

08.01.2014 - 13:03 Uhr

Genau das versuche ich zu beantworten, bevor ich Zeit investiere und migriere. Ich glaubs bisher auch nicht, aber Microsoft sagt immer ja 😉.

08.01.2014 - 12:56 Uhr

Wahrscheinlich lohnt es sich wirklich nur, wenn ich mal ein Administrator brauche. Für 4000 €, die ich pro Monat zahlen müsste, kann ich mir dann auch einiges bei Azure leisten (Annahme: Die Administration kann dann ein Entwickler nebenher machen).

08.01.2014 - 12:45 Uhr

Ich habe mir den Beitrag extra nochmal durchgelesen, aber leider hat niemand dort wirklich Erfahrung mit Azure (1,2 Mini-Instanzen zählen für micht nicht). Deshalb hatte ich gehofft, mit der Erweiterung auf AWS & Co. auch Infos von Leuten mit mehr Erfahrung in Cloud-Architekturen zu bekommen.

Auch CloudFlare hilft mir leider nicht (hatte deinen Artikel sogar gelesen), CDN und OutputCaching kann ich natürlich auch mit normaled hosted Servern nutzen, habe im Moment alle statischen Inhalte auch in einem Blob-Storage, aber das sind keine Kosten.

PS: Bei welchem Server-Anbieter bist du?

08.01.2014 - 12:13 Uhr

Hallo zusammen,

ich suche Leute, die Erfahrung mit Azure, AWS, Heroku oder einem anderen PaaS-Anbieter haben und ein bisschen was über die Kosten erzählen können. Wir sind von Azure auf einen normalen Server gewechselt, weil Azure einfach viel zu teuer war. Der jetzige Server hat 8 Cores und 32GB RAM für 120€ im Monat. Wir haben ca. 700k Besucher pro Monat. Das würde bei Azure mindestens das Dreifache kosten, wenn nicht mehr. Die Zeit, die ich für Administration brauche ist noch ungefähr gleich.

Ich glaube aber, dass mit steigender Last, das ganze wieder zugunsten von Azure kippen könne. Wenn ich nämlich eine höhere Ausfallsicherheit brauche, Loadbalancing, mehrere Server und sowohl die Server-Kosten, aber insbesondere auch die Kosten durch Administration erheblich steigen. Hat jemand Erfahrung gemacht oder eine eigene, größere Webseite laufen (vll. mal 5 oder 10Mio Besucher pro Moanat) und kann bisschen was zu der Kostenentwicklung sagen?

VG,
Sebastian

04.01.2014 - 22:01 Uhr

Die maximale Objektgröße ist doch 2GB, nicht die Heap-Größe.

12000x16000x32bit = 700 MB (+/-), sollte also passen und tut bei mir auch. Hast du davor schon ein paar Bilder erstellt? Eventuell geht dann wirklich der Heap alle, weil das Bild zu groß ist und im Large-Object-Heap liegt. Objekte in diesem Speicherbereich werden nicht verschoben, es kann also passieren, dass dein Speicher zu sehr fragmentiert ist.

04.01.2014 - 21:51 Uhr

Also mir kommt das ein bisschen naiv vor, das solltest du dir doch überlegen, bevor du dich selbsständig machst.

Ich war vor 2 Jahren zuletzt in Projektarbeit selbsständig. Für mich haben mehrere Dinge gut funktioniert:

  1. Eigene Kontakte: Nichts ist wichtiger. Suche dir einen Job, z.B. als freier Mitarbeiter oder auch als Halbzeitkraft und sammel Kontakte zu Firmen. Ein Großteil meiner Kunden kamen über Firmen, bei denen ich früher gearbeitet habe, oder bei denen ich Mitarbeiter kannte. Suche andere Freelancer und erstelle einen gemeinsamen Auftritt, so kannst du dein Netzwerk massiv erhöhen und ihr könnte euch gegenseitig Aufträge zuspielen. Außerdem profitiert Ihr eventuell von gemeinsamen Referenzen und man kann, falls nötig auch bisschen mit Steuern rumtricksen.

  2. Entwickel coole Projekte: Mir hat Imagetools richtig weitergeholfen. Die Kunden haben gleich eine Referenz mit Source-Code und sehen deinen Wert. Ist dein Projekt gefragt, werden andere Entwickler zwangsläufig um Support bitten. Das ist eine gute Gelegenheit um dein Netzwerk zu erweitern.

  3. Mache dich bekannt. Eine hohe Aktivität im Forum oder auch ein MVP-Titel von Microsoft sagt meiner Meinung nach überhaupt nix über dein Können aus, aber es hilft, dich zu verkaufen und das ist extrem wichtig. Sei aktiv, helfe in einem Forum, schreibe ein Blog, schreibe Artikel, am besten sogar in einer Zeitschrift (die suchen eigentlich immer Leute).

  4. Xing und LinkedIn: Hier tummeln sich relativ viele Headhunter. Wenn du dich aktiv drum kümmerst und flexibel bist, was dein Arbeitsort angeht, kannst du auf jeden Fall was als Einstieg finden. Man kann gut 2-10 Angebote pro Woche bekommen. Du könntest auch einfach die betreffenden Gruppen und interessante Profile besuchen, die jeweiligen Personen sehen dann, dass du ihr Profil besucht hast und das du interessant bist. Das ist zwar viel arbeit, lässt sich aber auch Automatisieren 😉. Hast du ein gutes Produkt, zum Beispiel für Entwickler, kannst du auch in Foren nach passenden Threads suchen und dich entsprechend positieren. Sei aber nicht zu aufdringlich. "Das geht am besten mit XYZ, ist aber extrem aufwändig. Einfacher und schneller gehts mit meinem Produkt ABC." (Schreibe ein bisschen mehr über die Lösung ohne dein Produkt und bekenne dich dazu, dass du der Entwickler bist, die Leute finden es eh raus)

Alles in allem solltest du schon ein Jahr einplanen um dich auf die Selbsständigkeit vorzubereiten. Du brauchst gerade im ersten Jahr eine Menge Geld für Anschaffungen und Steuervorauszahlung, das sollte man nicht unterschätzen.

03.01.2014 - 12:56 Uhr

Ich könnte mir vorstellen, dass die Schleife durch die Vererbung entsteht:

Der Serializer löst IInventory nach BaseInventory auf, geht alle Basisklassen/Interfaces durch, findet IInventory, löst nach BaseInventory auf, geht alle Basisklasssen/Interfaces durch...

Schau doch mal wie oft ReadJson aufgerufen wird. Evtl. musst du prüfen, ob exisitingValue null ist.

11.12.2013 - 15:39 Uhr

Der Context ist so weit ich nicht weiß nicht threadsicher. Suche doch doch mal nach dem Pattern UnitOfWork im Zusammenhang mit dem Entity-Framework.

10.12.2013 - 18:26 Uhr

Du kannst dir auch einen Generator schreiben. Bei mir sieht das dann so aus:

<schema>
<entity name="User" base="BaseEntity" note="Defines an user for the backend.">
<field name="Username" type="string" maxLength="100" minLength="4" required="true"
note="Username between 4 and 100 characters." />
<field name="Password" type="string" maxLength="100" minLength="20" required="true"
note="The encrypted password of the user." />
<field name="Mail" type="string" validator="Mail" required="true"
note="The mail address of the user." />
<field name="Salary" type="double" dataType="Currency" minValue="35500.0" maxValue="55000.0"
note="The salary of the user." />
</entity>

<model from="User" name="UserReadShortDTO" type="Read" includeDerived="true">
<include field="Id" />
<include field="Mail" />
<include field="Username" />
</model>

<model from="User" name="UserReadDTO" type="Read">
<exclude field="Salary" />
</model>
</schema>

Das heißt die Modelle und Entitäten werden in XML definiert und die Mapper und Klassen werden alle generiert.