Eine andere Möglichkeit besteht darin, für diese Klasse nur ein Interface bereit zu stellen (oder abstrakte Basisklasse) und die Implementierung private zu machen.
Das schöne daran ist, dass dderKlasse noch invidiuelle Methoden und Eigenschaften hinzufügen kannst, die intern nötig sind. Ein Beispiel wäre zum Beispiel der IEnumerator
Klar geht das. Mach dir erstmal vertraut, wie Html Formulare funktionieren. Meistens werden das POST Requests sein.
POST (HTTP)
Man würde so vorgehen:
Mit Regulären Ausdrücken oder zum Beispiel dem HtmlAgilityPack (https://htmlagilitypack.codeplex.com) kannst du Formularelemente auslesen.
Das werden in erster Linie Input Felder:
http://www.w3schools.com/tags/tag_input.asp und ComboBoxen (Select) sein:
http://www.w3schools.com/tags/tag_select.asp
Der Name (name="XXX") gibt darüber auskunft, wie du den POST Request erstellen musst, nämlich XXX=Wert1&XYZ=Wert2
Zusätzlich kannst du auch Elemente wie Labels oder Fieldset auslesen.
Winforms / WPF Formular erstellen und Usereingabe auslesen
POST Request erstellen und an die URL schicken, die im Formular Element angegeben ist, mit HtmlAgilityPack Antwort auslesen, parsen und anzeigen.
Vll. ist ein Dictionary einfach die falsche Datenstruktur?
http://blogs.msdn.com/b/dotnet/archive/2014/08/05/multidictionary-becomes-multivaluedictionary.aspx
Uncle Bob hat ein paar gute Videos gemacht: https://cleancoders.com/category/advanced-tdd
Kosten zwar Geld, sind aber sehr lang und auch recht unterhaltsam (wenn auch ein bisschen übertrieben für meinen Geschmack 😉). Lohnt sich aber.
Ich persönlich mache die Granularität auch davon abhängig wie oft sich Code ändert. Business Logik ändert sich bei uns einfach oft. Wir sind ein Startup, Anforderungen ändern sich, man probiert ein Feature aus, verwirft es dann wieder usw. Ich habe auch auf einem sehr granularen Level angefangen, wurde damit einfach nicht glücklich. Das hat so viel Zeit für Refactoring von Tests gebraucht, dass ich irgendwann frustriert alle Tests weggeschmissen habe. Das ist also auch nicht Sinn der Sache.
Zeige doch einfach mal den Code der Authentication Middleware. Was ich vermute:
Wenn du die oben gezeigte Middleware jeden Request behandelt, dann bekommst du eine Redirect Loop, weil bei jedem Request die Middleware wieder den Redirect macht. Wenn du das auf solchen Basis Middlewares machen willst, bräuchtest du am besten 2:
Das geht dann z.B. so
app.Map("login", path => path.Use<LoginMiddleware>());
// AuthenticationMiddleware
public async override Task Invoke(IOwinContext context)
{
if (context.Request.Path != "Login" && IsNotAuthentication())
{
context.Response.Redirect("/login?redirectUrl=" + context.Request.Uri);
}
}
Was verwendest du denn als Authentifizierungsmethode?
BasicAuth? Cookies?
Ich weiß nicht, was du mit "Nach erfolgreicher Authentifizierung meinst", aber wenn du sowas hast wie
if (IsValidUser(...))
{
context.Response.Redirect("...");
}
Dann bekommst du bei jedem Request für einen gültigen Benutzer einen Redirect. Diese Middleware darfst du natürlich nur auf deiner Login Page einsetzen oder du musst die Bedingung verbessern:
if (IsNotAuthorized() && IsValidUser(...))
{
Authorize();
context.Response.Redirect("...");
}
Außerdem würde ich auch die Middleware bei statischen Files nicht verwenden.
Z.B.
Für Angular machts keinen Unterschied ob der IIS direkt das Template ausliefert oder über WebAPI
[Route("templates/xyz.html")]
public async Task<HttpResponseMessage> GetXYZTemplate()
{
string tmpl = await DB.QueryTemplateAsync(...) ?? VirtualPathProvider.XXX(...);
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StringContent(tmpl);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
return response;
}
Ich mix teilweise MVC auch mit Angular und stelle ein paar Basiswerte direkt übers HTML bereit. Spart mir Requests.
Sonst brauche ich das aber auch nicht.
Du kannst die Angular-Views / Templates auch per WebAPI Action ausliefern, dann kannst du diese aus der Datenbank ablegen. Mit Caching usw. ist das auch sehr schnell.
Zwei weitere wichtige Faktoren betreffen die Performance im Zusammenhang mit Arrays:
Speicherverbrauch:
Ein Referenztyp verbraucht auf einem 64bit OS, 8 byte für den Zeiger (Referenz) und den Speicherverbrauch für die Klasse selbst: Also in deinem Fall nochmal 2x8 byte. Wenn man den Vektor nur mit floats abbilden würde (wie oft in der Game Entwicklung) wäre der Speicherverbrauch pro Vektor sogar doppelt so hoch.
Cache Effekte:
Legt man einen Wertetyp in ein Array ab, wird .NET das als Block direkt ablegen. Das heißt bei einem Array mit 100 Wertetypen liegen diese im Arbeitsspeicher direkt hintereinander. Bei einem Referenztype liegen nur die Pointer direkt im Arbeitspeicher in einem fetten Block, die eigentlichen Werte sind überall in deinem Heap verteilt. Zugriffe auf den Arbeitsspeicher werden von der CPU aber gecacht. Der Arbeitsspeicher wird Blockweise (Spaltenweise) gelesen und in den Cache geschrieben. Das heißt, wenn du z.B. ein Array von Wertetypen bearbeitest ist es sehr wahrscheinlich, dass nach dem Laden des ersten Eintrags die nächsten Einträge schon im Cache liegen und sehr schnell verarbeitet werden können.
Btw: Falls du viele Daten verarbeiten musst, solltest du unbedingt versuchen deine Datentypen ein mehfaches von 8 byte zu geben. Also anstatt z.B.
class { long, int, int bye } überprüfe, ob ein integer vll. nicht ein short sein kann, z.B. class { long, int, short, byte }. Der Grund: .Der Arbeitsspeicher ist in Blöcken zu 8 Byte (ein Word) eingeteilt. Das zusätzliche byte wird also dafür sorgen, dass alle Instanzen der Klasse plötzlich doppelt so viel Speicher belegen. Das hat mir in einem Szenario hier schon 2GB Arbeitsspeicher gekostet 😉
Im Prinzip gibt es nur eine Transformation, die halt auf 3 Matrizen aufgeteilt wird.
Über die Projektionsmatrix projiziert man vom 3D/2D Koordinaten System der Welt auf das 2D Screen Koordinatensystem und das muss ja nicht unbedingt 1:1 sein, wie man es in 2D oft macht 😉
Beim SpriteBatch ist das natürlich eine andere Sache, da hier die Projektionsmatrix verwaltet wird.
Warum nicht Projektionsmatrix? Das wäre für mich die logische Wahl.
Man wählt ein Koordinatensystem mit 1 = 1Meter. Dann transformiert die World Matrix vom lokalen Objektkoordinatensystem in das globale (mit gleich bleibender Einheit).
Die View Matrix in den ViewSpace (immer noch gleiche Einheiten).
Die Projektionsmatrix transformiert dann in den Screen Space mit 1Meter = XXX Pixel.
Ich glaube so wäre es wirklich am einfachsten. Alle Berechnungen bis zum Bewegen der Kamera bleiben im gleichen Koordinatensystem.
Du kannst es über die View oder Projektionsmatrix machen (vll. besser Projection)
Hi Christian,
ja das war nur ein Beispiel. Hatte ich gerade im Kopf und liefert auch noch viel Code für Animationen, zwei Methoden zur Matrix-Erzeugung habe ich ja auch erwähnt 😉
Die Matrixmultiplikationen führt man dann ja auch oft auf der Grafikkarte durch (bzw. berechnet die ViewProjectionMatrix vor) und sollten überhaupt nicht ins Gewicht fallen.
Viel wichtiger werden dann die Anzahl der Draw Calls.
Hi,
natürlich ist der Artikel für WPF gedacht, ich bin mir aber sicher, dass man Ihn einfach umprogrammieren kann. Im Prinzip sind Translatations in WPF nur Matrizen, die dann auf die Elemente angewendet werden. Wenn es sich um RenderTransformation handelt, dann ist das Layout ja auch gar nicht davon betroffen. Das gleiche Prinzip kannst du auch für XNA anwenden. Im Prinzip geht es mir nur um die Berechnungen, die dort durchgeführt werden. Das kann man analog übernehmen:
TranslateTransform => Matrix.CreateTranslate(x, y, 0) // Keine Z Transformation, wir sind ja in 2D
ScaleTransform => Matrix.CreateScale(zoom);
TransformationGroup => Multiplikation von Rotaton und TranslationMatrix
Und dann gibts viele weitere Analogien:
ViewportWidth => WindowWidth
ViewportHeight => WindowHeight
(Arg viel mehr steckt in WPF auch nicht dahinter)
Du musst dir eben überlegen, wie du deine ViewMatrix berechnest und da hilft der Artikel schon sehr.
In dem Artikel wird eine ScaleTransform und ein TranslateTransform verwendet. Das ist analog zu einer SkalierungsMatrix multipliziert mit einer TranslationsMatrix (= View Matrix)
Deshalb ist der Artikel schon genau das was du suchst, denke ich.
Du benötigst noch eine Translation. Schau dir mal folgenden Artikel an:
Habs gefunden. Das Problem lag in der Complete Methode:
Kann die Antwort nicht serialisiert werden (Dafür gibt es leider auch zig verschiede Exception Typen, dann schlägt die Response fehl und es gibt ein Memory Leak und der await wartet ewig.
Habs temporär mal so gelöst:
task.ContinueWith(t =>
{
try
{
if (t.IsFaulted)
{
tcs.TrySetException(t.Exception);
}
else if (t.IsCanceled)
{
tcs.TrySetCancelled();
}
else
{
tcs.TrySetResult(t.Result);
}
}
catch
{
tcs.TrySetException(new RemotingException("Failed to serialize the response correctly."));
}
}, TaskContinuationOptions.ExecuteSynchronously);
@Palin: Du hast im Prinzip natürlich Recht, freigeben schadet nicht.
Ich habe bisher aber mehr rausgefunden. Ich habe außerhalb des Client Aufrufs und in der Server Methode jeweils mal einen Counter inkrementiert und dekrementiert, also so:
Interlocked.Increment(ref counter);
await RemoteTasks.ClientComplete(...);
Interlocked.Decrement(ref counter);
Trace(counter);
Interessant ist: Der äußere Counter steigt stets und der innere Counter ist nahe bei 0 (also geht mal temporär auf 1,2 ... 10 hoch, sinkt aber wieder).
Das sieht mir deshalb eher nach einem Deadlock aus. Das ganze passiert aber nur bei einem bestimmten Plugin.
Ich hätte noch mehr Informationen geben sollten.
Bei MarshalByRefObject greift der GC nicht direkt, weil das System Referenzen verwaltet und diese nach einer gewissen Dauer ohne Aufrufe von alleine freigibt (Im Standardverhalten habe ich dann aber Probleme mit den langen Operationen, deshalb deaktiviere ich das Verhalten hier in dem ich den LifetimeService mit InitializeLifetimeService deaktiviere).
Ich habe rausgefunden, dass die v.a. Referenzen von RemoteTask hängen, weil diese von ServerIdentity gehalten werden (also genau das Disconnect).
Nicht im Zusammenhang mit Dispose 😉
Hallo zusammen,
ich habe ein Plugin System mit AppDomains entwickelt. Um auch async/await zu unterstützen, kapsel ich Tasks weg (Siehe Code). Da ich teilweise auch lange dauernde Operationen habe, deaktiviere ich den Lifetime Manager und entferne die Objekte manuell.
Dabei habe ich aber teilweise Memory Leaks, die schwer nachzuvollziehen sind. Lokal habe ich keine Indizien, ich bemerke sie aber, wenn ich MemoryDumps anschaue und viele Instanzen von RemoteTask finde.
Hier mal der Code:
// Wrapper around TaskCompletionSource
public sealed class RemoteTaskCompletionSource<T> : MarshalByRefObject, IDisposable
{
private readonly TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
public override object InitializeLifetimeService() => null;
public void Dispose() => RemotingServices.Disconnect(this);
public bool TrySetResult(T result) => tcs.TrySetResult(result);
public bool TrySetCancelled() => tcs.TrySetCanceled();
public bool TrySetException(Exception ex) => tcs.TrySetException(ex);
public Task<T> Task => tcs.Task;
}
public sealed class RemoteTask<T> : MarshalByRefObject, IDisposable
{
private readonly CancellationTokenSource cts = new CancellationTokenSource();
private readonly Task<T> task;
internal RemoteTask(Func<CancellationToken, Task<T>> starter)
{
this.task = starter(cts.Token);
}
public override object InitializeLifetimeService() => null;
public void Dispose() => RemotingServices.Disconnect(this);
internal void Complete(RemoteTaskCompletionSource<T> tcs)
{
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
tcs.TrySetException(t.Exception);
}
else if (t.IsCanceled)
{
tcs.TrySetCancelled();
}
else
{
tcs.TrySetResult(t.Result);
}
}, TaskContinuationOptions.ExecuteSynchronously);
}
internal void Cancel() => cts.Cancel();
}
public static class RemoteTasks
{
public static async Task<T> ClientComplete<T>(RemoteTask<T> remoteTask, CancellationToken cancellationToken)
{
T result;
using (remoteTask)
{
using (cancellationToken.Register(remoteTask.Cancel))
{
using (RemoteTaskCompletionSource<T> tcs = new RemoteTaskCompletionSource<T>())
{
remoteTask.Complete(tcs);
result = await tcs.Task;
}
}
await Task.Yield();
}
return result;
}
public static RemoteTask<T> ServerStart<T>(Func<CancellationToken, Task<T>> func)
{
return new RemoteTask<T>(func);
}
}
// Usage in plugin
public class Plugin()
{
public RemoteTask<int> DoXAsync()
{
return RemoteTasks.ServerStart(async t => { await Task.Delay(1); return 123; });
}
}
// Usage in consumer
await RemoteTasks.ClientComplete(plugin.DoXAsync(), CancellationToken.None);
Hat jemand eine Idee? Ich habe bisher noch keinerlei Anhaltspunkte 😦
Ich würde mir mal Azure ServiceBus anschauen. Dann hast du auch keinen Stress, wenn man in verschiedenen Netzwerken ist.
Entweder
By.CssSelector(".listitem_new")
By.ClassName("listitem_new")
Das ist kein CSS Selector, ganz einfach 😉
Das ist mir schon klar. Aber irgendwann muss man halt auch da Abstriche machen. Die Investition in Plugin Systeme usw. lohnt sich ja erst bei vielen Projekten. Aktuell habe ich das Problem gar nicht, weil ich gerade keine typischen LOB-Projekte mehr habe, aber es würde mich schon sehr interessieren, ob man die Wiederverwendbarkeit auf ein neues Level anheben kann und wer mit welchen Tools Erfahrung hat.
Ich hätte das vll. weiter spezifizieren müssen. Meine Hoffnung ist, dass ich für Geschäftsanwendungen irgendwann 90% des Codes generieren oder konfigurieren kann. Natürlich mache ich nicht immer die gleiche Arbeit, sie ähnelt sich oft aber so sehr (auch über Unternehmensgrenzen und verschiedene Arbeitgeber hinweg), dass der Eindruck wächst, hier wird Potential verschwendet.
Ob man jetzt eine Software zur Lagerverwaltung entwickelt, an einem CRM mitarbeitet, nur ein kleines Tool schreibt um eine Excel Datei zu ersetzen, die Gemeinsamkeiten sind hier so groß, dass man das besser nutzen sollte. Man kann hier natürlich Code auslagern und das ist auch ein konstanter Prozess, das aber so zu machen, dass er wirklich universell einsetzbar ist, ist aufwändig und im Context einer kleineren Firma auch nicht rentabel.
Hallo zusammen,
ich bin immer wieder genervt davon, dass ich jedes mal das gleiche wieder und wieder programmiere. Natürliche baue ich auch meine eigenen Frameworks, habe aber immer noch die Hoffnung, dass ich 90% der SW einfach irgendwann zusammenklicken oder Generieren kann. Vielleicht auch nur für einzelne (Micro)Services wie z.B. irgendwelche Verwaltungsmodule oder andere Geschäftsbereiche. Diese Hoffnung scheinen noch mehr Entwickler zu haben und es gibt ja auch eine Vielzahl an Tools wie Lightswitch, RIA Services, Mobile Services, Podio, die ein Teil des Prozesses abnehmen.
Ich bin bisher noch mit keinem Tool warm genommen, weil die Erweiterbarkeit schlecht war oder die Performance grausam, oder die UI einfach nicht auf dem neuesten Stand.
Mich würde interessieren, wie ihr zu Lightswitch & Co. steht, ob und wenn ja, welche Tools ihr verwendet habt und warum ihr vll. ein Tool nicht verwendet konntet.
Das sieht richtig Klasse aus. Mir sind noch 2,3 Kleinigkeiten aufgefallen, aber das weißt du bestimmt alles. Die Animationen finde ich aber bisschen zu nervig nach einer Zeit, da würde ich evtl. bisschen weniger machne oder schneller.
Ich gebe dir noch zwei Alternativen:
https://clearscript.codeplex.com/
Ich finde das ist überhaupt nicht die Aufgabe des ViewModels sondern die richtige Aufgabe des Controls. Im ViewModel sollte es auch kein großes Problem sein, 1.000.000 Einträge zu halten. Je nach Daten hast du ja nur 3-4 MB.
Für mich geht das in Richtung VirtualizingPanel. https://uhimaniavwp.codeplex.com/
Wenn das gut funktioniert brauchst du gar kein CustomControl mehr, du kannst natürlich davon erben, insbesondere wenn du ein eigenes Format für VM's hast (ähnlich zu ObservableCollection).
Btw: In der Doku zu VirtualizingPanel schreibt MS auch, dass es keinen Sinn macht, Zustände im Container(= Item) zu speichern (z.B. IsExpanded). Macht ja auch Sinn, weil der Container für ein anderes Datenobjekt wiederverwendet werden kann.
Also SSL Validierung kann man ausschalten:
ServicePointManager.ServerCertificateValidationCallback Property
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Ich kapier es immer noch nicht. Operatoren sind in erster Linie nur syntaktischer Zucker. Allerdings sind die aus Gründen der Symmetrie statisch (siehe Link) und können deshalb nicht Teil von Interfaces sein. Law of Demeter sagt ja auch nicht: Rede mit Niemandem
Das ist einfache eine Design-Entscheidung gewesen: Why are overloaded operators always static in C#?
Den Zusammenhang mit Law of Demeter sehe ich jetzt nicht.
Vielleicht sind die Begriffe falsch, aber es passiert beides: Der Generic wird Type wird vom Compiler erzeugt und Informationen über alle Typparameter inklusive Constraints hinterlegt.
Deshalb ist es auch nicht möglich mit Reflection ungültigen Typen für die Parameter zu erzeugen.
In C++ sind das einfach zwei verschiedene Klassen.
Das where (nennt sich constraints) würde grundsätzlich gehen, du könntest zum Beispiel Formulieren, dass alle T's bestimmte mathematische Operationen unterstützen müssen, ABER...
Beispielsweise:
interface ISupportPlus<T>
{
T Add(T other);
}
class Vector<T> where T : ISupportsPlus<T>
{
T x, y, z;
Vector<T> Add(Vector<T> other)
{
return new Vector<T>(x.Add(other.x), ...);
}
}
Aber wie gesagt: Es geht einfach nicht 😦
Du kommst bestimmt von C++, dort werden die Templates vom Compiler auch nur als Templates genutzt und nur die konkreten Typen kompiliert, z.B. Vector<float>. In C# werden Generics aber zur Laufzeit aufgelöst und dann muss der Compiler eben die Rahmenbedingungen kennen.
Leider ist heir C# nicht mächtig genug.
EDIT: Wenn du sowas machen willst, würde ich einfach Code Generierung anwenden.
Das Stichwort ist: Render to texture oder RenderTarget
z.B. http://sharpdx.org/forum/5-api-usage/107-render-target-texture
Du erstellst ein RenderTarget mit der Größe deines Bilds, darin zeichnest du ein Rechteck mit deiner Textur, welches das ganze Bild einnimmt und wendest den Shader an. Das RenderTarget kannst du dann abspeichern.
Die selbe Methode wird auch bei Reflexionen und Schatten und PostProcessing angewendet.
Du kannst einen eigenen IUserStore implementieren und dann nur die passenden Interfaces implementieren:
https://msdn.microsoft.com/en-us/library/dn613259%28v=vs.108%29.aspx
Das geht immer noch. Ich dachte StreamContent macht das, aber anscheinend nicht. Vielleicht hilft dir das:
http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/
Wenn nicht, PushStreamContent funktioniert auf jeden Fall.
Wenn du wirklich Videos streamen willst (klang gerade eher nach einzelnen Bildern) würde ich nach fertigen Lösungen suchen, auch von Microsoft gibt es da irgendwas (Media Server oder so).
Ich würde mir einen Service schreiben (Windows Service z.B.) der regelmäßig die Bilder aller Kameras ausliest und in ein Verzeichnis schreibt. Pro Kamera kannst du ja einen Ordner verwenden und Zusatzinfos in den Dateinamen schreiben. Außerdem sollte der Service alte Bilder löschen (du könntest ja eine max Anzahl Bilder oder eine Größe definieren, damit deine HDD nicht voll läuft). Außerdem würde ich ein Thumbnail generieren, wenn du ein neues Bild reinbekommst.
Diese Order liegt entweder in deiner Webseite und ist per IIS erreichbar oder (besser?) du machst das per Controller: http://stackoverflow.com/questions/186062/can-an-asp-net-mvc-controller-return-an-image
Das gibt dir auch den Vorteil, dass du eine History hast (Dazu das Thumbnail).
Für den Service kann ich dir Topshelf empfehlen: http://topshelf-project.com/
Bei Erfahrung ist das max ein Tag Arbeit.
Das mit static kommt von Java: Java - Nested Classes
Du musst den Inhalt ja nur Streamen, z.B. mit PushStreamContent, btw. StreamContent.
Außerdem kann es hilfreich sein, wenn man den Download fortsetzen kann: ASP.NET Web API file download service with resume support
Protobuf: https://github.com/google/protobuf
Sehr schnelles und einfaches Binärformat, verwenden wir hier für interne Kommunikation überwiegend auch. Gibt Implementierungen für Java und C# und eine Beschreibungssprache mit deren Hilfe Serialisierungsklassen generiert werden können (analog zu XML Schema oder XSD).
Schau mal das Tutorial an:
http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr
Bei Pacman gibts genau 4 Geister, jeder hat eine eigene Strategie.
Schau mal hier rein: http://home.comcast.net/~jpittman2/pacman/pacmandossier.html#Chapter_4
Du kannst natürlich deinen eigenen Ansatz reinbringen, aber für den Anfang ist das vll. nicht schlecht.
Ich würde mir um dein Item ein Container bauen und dann selber catchen:
class ProcessItem<T>
{
T Result { get; set; }
Exception { get; set; }
}
Es gibt sogar PaaS Lösungen für Online-Games: https://www.exitgames.com/en/Realtime
Kannst du ja mal anschauen.