E
Edward Yang
When it comes to ViewState in ASP.NET, I have a mixed feeling of both
love and hate. For love, it simplifies many aspects of common tasks; for
hate, it bloats web pages with large amount of cryptic (though not
really ) text.
I find that LOS formatter is not as effecient as what Microsoft claims.
It takes up much of CPU time. For example, it is very obvious in CPU
utilization (up to 50% for one page) when serializing/deseriailzing a
dataset that is constructed from an XML file about 54kb. And to the end
user, there is a significant and noticable delay when the ASP.NET
runtime is doing the work.
Please pay speical attention - that is only *ONE* page.
In our development, I have been trying to find a solution to minimize
the negative effect of ViewState.
First, I read several articles on ViewState and write a class that
inherits from the Page class and overrides
LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium.
I saved ViewState data into Session and a short time later into Cache,
because I thought Cache is disk file-based (which is wrong).
Since server memory is precious (Our production server has 2gb memory
and dual CPUs), I then saved ViewSate to disk files. But this did not
solve the problem, it only lowers network traffic and speeds up page
postbacks a little.
CPU utilization is still high, since I use LOS formatter. The reason is
that binary formatter won't work on the viewState object passed in to
SavePageStateToPersistenceMedium. The Triplet and Pair classes are not
made serializable! That's a *BIG* surpise to me.
So there has to be a way out. I finally worked out a solution, in only 6
hours . Alghough this solution is working perfectly for my projects,
but there certainly places that need improvments. So I'll outline my
idea here.
Since Triplet/Pair classes are not serializable by binary formatter (due
to unknown reasons that I cannot comprehend), I think I can replace them
with my own classes. So here they, simple indeed:
<Serializable()> _
Public Class MyTriplet
Public First As Object
Public Second As Object
Public Third As Object
End Class
<Serializable()> _
Public Class MyPair
Public First As Object
Public Second As Object
End Class
Next, I have to parse the viewState object passed to
SavePageStateToPersistenceMedium so that whenever a Triplet or Pair
object is found, I replace it with my own.
Below is what my code that does the job:
Public Shared Function ParseObject(ByVal o As Object) As Object
If o Is Nothing Then Return Nothing
'Debug.WriteLine(TypeName(o))
If TypeOf o Is Triplet Then
Return Parse(CType(o, Triplet))
ElseIf TypeOf o Is Pair Then
Return Parse(CType(o, Pair))
ElseIf TypeOf o Is Array Then
Return Parse(CType(o, Object()))
ElseIf TypeOf o Is ArrayList Then
Return Parse(CType(o, ArrayList))
ElseIf TypeOf o Is Hashtable Then
Return Parse(CType(o, Hashtable))
Else
Return o
End If
End Function
Private Shared Function Parse(ByVal a As ArrayList) As ArrayList
If a Is Nothing Then Return Nothing
Dim i As Integer
For i = 0 To a.Count - 1
a(i) = ParseObject(a(i))
Next
Return a
End Function
Private Shared Function Parse(ByVal triplet As Triplet) As
MyTriplet
If triplet Is Nothing Then Return Nothing
Dim x As MyTriplet
x = New MyTriplet()
x.First = ParseObject(triplet.First)
x.Second = ParseObject(triplet.Second)
x.Third = ParseObject(triplet.Third)
Return x
End Function
Private Shared Function Parse(ByVal pair As Pair) As MyPair
If pair Is Nothing Then Return Nothing
Dim x As MyPair
x = New MyPair()
x.First = ParseObject(pair.First)
x.Second = ParseObject(pair.Second)
Return x
End Function
When deserializing, the job is just a reverse process - find MyTriplet
or MyPair and restore them to Triplet and MyPair.
Sorry I cannot post all of my code here, because they are real code of
our existing projects.
So far, it is good and working. In my test project, a page that usually
takes a noticable serveral seconds to postback now refreshes instantly.
The CPU utilization is almost zero.
Just my 2 cents. I hope there will be feedback on this topic so that I
can improve current solution. I need feedback especially from Microsoft;
they really have done the work better.
love and hate. For love, it simplifies many aspects of common tasks; for
hate, it bloats web pages with large amount of cryptic (though not
really ) text.
I find that LOS formatter is not as effecient as what Microsoft claims.
It takes up much of CPU time. For example, it is very obvious in CPU
utilization (up to 50% for one page) when serializing/deseriailzing a
dataset that is constructed from an XML file about 54kb. And to the end
user, there is a significant and noticable delay when the ASP.NET
runtime is doing the work.
Please pay speical attention - that is only *ONE* page.
In our development, I have been trying to find a solution to minimize
the negative effect of ViewState.
First, I read several articles on ViewState and write a class that
inherits from the Page class and overrides
LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium.
I saved ViewState data into Session and a short time later into Cache,
because I thought Cache is disk file-based (which is wrong).
Since server memory is precious (Our production server has 2gb memory
and dual CPUs), I then saved ViewSate to disk files. But this did not
solve the problem, it only lowers network traffic and speeds up page
postbacks a little.
CPU utilization is still high, since I use LOS formatter. The reason is
that binary formatter won't work on the viewState object passed in to
SavePageStateToPersistenceMedium. The Triplet and Pair classes are not
made serializable! That's a *BIG* surpise to me.
So there has to be a way out. I finally worked out a solution, in only 6
hours . Alghough this solution is working perfectly for my projects,
but there certainly places that need improvments. So I'll outline my
idea here.
Since Triplet/Pair classes are not serializable by binary formatter (due
to unknown reasons that I cannot comprehend), I think I can replace them
with my own classes. So here they, simple indeed:
<Serializable()> _
Public Class MyTriplet
Public First As Object
Public Second As Object
Public Third As Object
End Class
<Serializable()> _
Public Class MyPair
Public First As Object
Public Second As Object
End Class
Next, I have to parse the viewState object passed to
SavePageStateToPersistenceMedium so that whenever a Triplet or Pair
object is found, I replace it with my own.
Below is what my code that does the job:
Public Shared Function ParseObject(ByVal o As Object) As Object
If o Is Nothing Then Return Nothing
'Debug.WriteLine(TypeName(o))
If TypeOf o Is Triplet Then
Return Parse(CType(o, Triplet))
ElseIf TypeOf o Is Pair Then
Return Parse(CType(o, Pair))
ElseIf TypeOf o Is Array Then
Return Parse(CType(o, Object()))
ElseIf TypeOf o Is ArrayList Then
Return Parse(CType(o, ArrayList))
ElseIf TypeOf o Is Hashtable Then
Return Parse(CType(o, Hashtable))
Else
Return o
End If
End Function
Private Shared Function Parse(ByVal a As ArrayList) As ArrayList
If a Is Nothing Then Return Nothing
Dim i As Integer
For i = 0 To a.Count - 1
a(i) = ParseObject(a(i))
Next
Return a
End Function
Private Shared Function Parse(ByVal triplet As Triplet) As
MyTriplet
If triplet Is Nothing Then Return Nothing
Dim x As MyTriplet
x = New MyTriplet()
x.First = ParseObject(triplet.First)
x.Second = ParseObject(triplet.Second)
x.Third = ParseObject(triplet.Third)
Return x
End Function
Private Shared Function Parse(ByVal pair As Pair) As MyPair
If pair Is Nothing Then Return Nothing
Dim x As MyPair
x = New MyPair()
x.First = ParseObject(pair.First)
x.Second = ParseObject(pair.Second)
Return x
End Function
When deserializing, the job is just a reverse process - find MyTriplet
or MyPair and restore them to Triplet and MyPair.
Sorry I cannot post all of my code here, because they are real code of
our existing projects.
So far, it is good and working. In my test project, a page that usually
takes a noticable serveral seconds to postback now refreshes instantly.
The CPU utilization is almost zero.
Just my 2 cents. I hope there will be feedback on this topic so that I
can improve current solution. I need feedback especially from Microsoft;
they really have done the work better.