About ViewState and LOS formatter

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.
 
B

bruce barker

the Triplet/Pair classes are not serializable because they hold generic
objects which may not be.

while I have used
LoadPageStateFromPersistenceMedium/SavePageStateToPersistenceMedium for
intranet applications (to make grids work), I'd never use it for a
commerical grade app. it best to just store a session state id/key in
viewstate, and store session data in your session store.


-- bruce (sqlwork.com)



| 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top