Habe lange nichts geschrieben, da ich derzeit zu Hause umbaue und in Kürze mit meiner Familie die frisch renovierte Wohnung beziehen werde. Voraussichtlich irgendwann mitte Mai.
Ich programmiere nun seit vielen Jahren Webanwendungen mit der ein oder anderen Programmiersprache, seit ein paar Jahren auch beruflich im .Net Umfeld; gerne sogar! Unter anderem weil die Community groß ist und alles sehr gut dokumentiert ist. Trotzdem kommt es immer wieder vor, dass ich mich am Kopf kratzen muss, was zur Hölle die Entwickler bei Microsoft sich bei der ein oder anderen Sache so gedacht haben.
Montag, 16. April 2012
Donnerstag, 5. April 2012
Der sagenumwobene Viewstate
Seit ich mich im .Net Umfeld bewege, konnte ich die Sache mit diesem "Viewstate" nicht wirklich nachvollziehen. Seit vor einiger zeit das Problem aufkam, dass in einem unserer Produkte ein speichervorgang einer Seite mehrere Minuten dauern konnte, bin ich dem Problem auf den Grund gegangen und habe festgestellt, dass der Viewstate auf über 6MiB angewachsen war.
Die Seite als solches ist dabei aber recht einfach gestrickt und besteht im Grunde aus einer Tabelle mit 5 Spalten von Dropdownboxen, aus der eine Auswahl getroffen werden kann. Klar kommt da schnell eine Menge an Daten zusammen, zumal eine der Auswahlmöglichkeiten mehr als 100 Textbausteine enthalten kann.
Die Große Frage aber, die sich mir stellt: Warum so ein riesiger Viewstate für ein paar Dropdownboxen? Dieses nachverfolgt, stellt sich heraus, dass X-Mal der identische Inhalt der Textbausteine im Viewstate vorgehalten wird.
Zur Lösung des Problems habe ich ein Control in der Form einer Textbox erstellt, die beim "Lostippen" vorschläge zur Auswahl stellt, in denen der gesuchte Begriff vorkommt. Anschließend habe ich den ViewState für den Dialog abgeschaltet und der Performance-Gewinn war unbestreitbar.
ViewState? Wozu?
Hilfreich zu diesem Thema ist auch der folgende Artikel aus dem MSDN: "Ein mundgerechtes Stück ASP.NET ViewState"
Die Seite als solches ist dabei aber recht einfach gestrickt und besteht im Grunde aus einer Tabelle mit 5 Spalten von Dropdownboxen, aus der eine Auswahl getroffen werden kann. Klar kommt da schnell eine Menge an Daten zusammen, zumal eine der Auswahlmöglichkeiten mehr als 100 Textbausteine enthalten kann.
Die Große Frage aber, die sich mir stellt: Warum so ein riesiger Viewstate für ein paar Dropdownboxen? Dieses nachverfolgt, stellt sich heraus, dass X-Mal der identische Inhalt der Textbausteine im Viewstate vorgehalten wird.
Zur Lösung des Problems habe ich ein Control in der Form einer Textbox erstellt, die beim "Lostippen" vorschläge zur Auswahl stellt, in denen der gesuchte Begriff vorkommt. Anschließend habe ich den ViewState für den Dialog abgeschaltet und der Performance-Gewinn war unbestreitbar.
ViewState? Wozu?
Hilfreich zu diesem Thema ist auch der folgende Artikel aus dem MSDN: "Ein mundgerechtes Stück ASP.NET ViewState"
ViewState die Zweite...
Man nehme ein Grid und deaktiviere den ViewState für dieses, da das bekannte Anwachsen des Selbigen immer wieder zu Performance-Problemem führt, insbesondere wenn die Anwendung über eine schwachbrüstige Internetleitung aufgerufen wird.
Führt man nun über ein weiteres Steuerelement der Seite eine Aktion aus, die einen Postback mit sich bringt, wird das Grid neu an die Datenquelle gebunden und zuvor gemachte Eingaben sind verloren. Also doch der ViewState? Nein, lieber nicht. Um dieses Problem (was eigentlich keines ist) zu umschiffen habe ich folgende Klasse erstellt, welche vorhandene, aber nicht gespeicherte Angaben des Grids in der entsprechenden Datenquelle, dem DataView vornimmt, ganz ohne Viewstate.
Anschließend kann man je nach Belieben bestimmte Werte im Grid, bzw. der dazugehörigen DataView aktualisieren, sodass beim Laden die Datenbindung an eine aktualisierte View erfolgt.
Warum ich in obigem Beispiel die Culture der DataView auf "en-US" setze und später wieder auf die eigentliche Kultur, erklärt sich im Artikel "CultureInfo: Chaos im .Net"
Beispiel:
So far...
Führt man nun über ein weiteres Steuerelement der Seite eine Aktion aus, die einen Postback mit sich bringt, wird das Grid neu an die Datenquelle gebunden und zuvor gemachte Eingaben sind verloren. Also doch der ViewState? Nein, lieber nicht. Um dieses Problem (was eigentlich keines ist) zu umschiffen habe ich folgende Klasse erstellt, welche vorhandene, aber nicht gespeicherte Angaben des Grids in der entsprechenden Datenquelle, dem DataView vornimmt, ganz ohne Viewstate.
Public Class UpdateView Private _grid As RadGrid Private _assignments As SortedDictionary(Of String, String) = New SortedDictionary(Of String, String) Public Property Assignments As SortedDictionary(Of String, String) Get Return _assignments End Get Set(value As SortedDictionary(Of String, String)) _assignments = value End Set End Property Public ReadOnly Property Grid As RadGrid Get Return _grid End Get End Property Public Sub New(ByVal grid As RadGrid) Me._grid = grid End Sub Public Sub Update(ByRef dataView As DataView) Dim oldCulture As System.Globalization.CultureInfo = dataView.Table.Locale dataView.Table.Locale = New System.Globalization.CultureInfo("en-US") 'sonstige Änderungen übernehmen ohne MegaByte Weise Viewstate für's RadGrid For Each p As String In HttpContext.Current.Request.Params 'Request Parameter itereieren If p.Contains(_grid.UniqueID) Then 'prüfen ob der der aktuelle Eintrag zum RadGrid gehört Dim a = _grid.FindControl(p.Replace(_grid.UniqueID & "$", "")) 'das entsprechende Steuerelement finden If a IsNot Nothing Then If Assignments.Keys.Contains(a.ID) Then 'prüfen ob das Steuerelement zu aktualisieren ist Dim row = CType(a.Parent.NamingContainer, GridDataItem).ItemIndex 'entsprechende Row des RadGrids ermitteln dataView.Table.Rows(row).Item(Assignments(a.ID)) = HttpContext.Current.Request.Params(p) 'DataView-Feld mit dem entsprechenden Datum aktualisieren End If End If End If Next 'Ende dataView.Table.Locale = oldCulture End Sub End Class
Anschließend kann man je nach Belieben bestimmte Werte im Grid, bzw. der dazugehörigen DataView aktualisieren, sodass beim Laden die Datenbindung an eine aktualisierte View erfolgt.
Warum ich in obigem Beispiel die Culture der DataView auf "en-US" setze und später wieder auf die eigentliche Kultur, erklärt sich im Artikel "CultureInfo: Chaos im .Net"
Beispiel:
Dim updateView As LCT.Tools.UpdateView = New LCT.Tools.UpdateView(RadGrid) updateView.Assignments.Add("GridEditItemID1", "DataViewColumnName1") updateView.Assignments.Add("GridEditItemID2", "DataViewColumnName2") updateView.Update(DataView)
Mittwoch, 4. April 2012
Raspberry Pi
Habe soeben bei Farnell einen Raspberry Pi bestellt! Freue mich auf das tolle Spielzeug!
Sobald es da ist, werde ich mal schauen ob ich es als PDC für's Heimnetzwerk konfiguriert bekomme und teste was sonst noch mit der Kiste möglich ist.
Weitere Info über den Mini-Computer: http://www.raspberrypi.org/
Sobald es da ist, werde ich mal schauen ob ich es als PDC für's Heimnetzwerk konfiguriert bekomme und teste was sonst noch mit der Kiste möglich ist.
Weitere Info über den Mini-Computer: http://www.raspberrypi.org/
Dienstag, 3. April 2012
CultureInfo: Chaos im .Net
eine Dataview in einer ASP-Seite, die mit der Culture-Info "de-DE" initialisiert wird, verhält sich äußerst eigenartig, wenn man hier versucht einen "Double" wert in der View abzulegen, der beispielsweise über Post-Parameter (demzufolge als String) an das Script übergeben wird.
VB Beispiel:
Ebenso wird ein Cast von String nach Double in der Kultur "de-DE" m.E. falsch übersetzt, aus:
CDbl("41.5")
wird 415.0
Wow! Das klappt ja prima! Da bekommt man ein Double im String Format und wegen einer Culture-Einstellung wird diese missinterpretiert. Also wirklich, meine lieben Damen und Herren von Microsoft. Der Datentyp der Spalte ist Double und nur weil die CultureInfo auf "de-DE" steht wird ein ","(Komma) als Dezimaltrennzeichen angenommen. Solche formate grundsätzlich auf die angegebene Kultur anzuwenden ist zwar konsequent, allerdings aus meiner Sicht nicht praktikabel, da man als Entwickler von mehrsprachigen Anwendungen hier zusätlich noch beim Konvertieren von Werten auf die Ländereinstellung achten muss.
Seit ich programmiere sind double Werte mit einem .(Punkt) als Dezimaltrennzeichen versehen, warum wird im .Net davon abgewichen? Damit die Fehleranfälligkeit erhöht wird?
Eine ganz ähnliche Problematik ergibt sich zum Beispiel bei Datumswerten unter anderem im SQL-Server. Ich frage mich wirklich, warum sowas sein muss? Reicht es nicht sich programmatisch auf EIN EINZIGES Format (zum Beispiel das US-englische) zu beschränken und lediglich bei der Ausgabe/Anzeige der Werte in der Oberfläche eine entsprechende Konvertierung vorzunehmen?
VB Beispiel:
dataView.Table.Columns(x).DataType = GetType(Double)
dataView.Table.Rows(n).Item(x) = "45.2"
Console.WriteLine(dataView.Table.Rows(n).Item(x))
// Ausgabe: 452.0Ebenso wird ein Cast von String nach Double in der Kultur "de-DE" m.E. falsch übersetzt, aus:
CDbl("41.5")
wird 415.0
Wow! Das klappt ja prima! Da bekommt man ein Double im String Format und wegen einer Culture-Einstellung wird diese missinterpretiert. Also wirklich, meine lieben Damen und Herren von Microsoft. Der Datentyp der Spalte ist Double und nur weil die CultureInfo auf "de-DE" steht wird ein ","(Komma) als Dezimaltrennzeichen angenommen. Solche formate grundsätzlich auf die angegebene Kultur anzuwenden ist zwar konsequent, allerdings aus meiner Sicht nicht praktikabel, da man als Entwickler von mehrsprachigen Anwendungen hier zusätlich noch beim Konvertieren von Werten auf die Ländereinstellung achten muss.
Seit ich programmiere sind double Werte mit einem .(Punkt) als Dezimaltrennzeichen versehen, warum wird im .Net davon abgewichen? Damit die Fehleranfälligkeit erhöht wird?
Eine ganz ähnliche Problematik ergibt sich zum Beispiel bei Datumswerten unter anderem im SQL-Server. Ich frage mich wirklich, warum sowas sein muss? Reicht es nicht sich programmatisch auf EIN EINZIGES Format (zum Beispiel das US-englische) zu beschränken und lediglich bei der Ausgabe/Anzeige der Werte in der Oberfläche eine entsprechende Konvertierung vorzunehmen?
Abonnieren
Posts (Atom)